springboot线程池_SpringBoot入门建站全系列(二十二)异步任务执行的几种方式

news/2024/5/10 23:24:37/文章来源:https://blog.csdn.net/weixin_39607447/article/details/111037010

5ffd9a92dad056d300500e92e4b8a137.png

SpringBoot入门建站全系列(二十二)异步任务执行的几种方式

一、概述

异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行。

实现异步任务的方式有很多,但是可以总结为多线程异步和多进程异步。

多线程异步:

  • 多线程实现异步就是新建个线程,将任务交给新线程执行。
  • 不管是自己new Thread实现异步,还是使用ThreadPoolTaskExecutor线程池,还是使用Spring的@EnableAsync注解,这些都是多线程实现的异步。

多进程异步:

  • 将任务交给另外一个进程处理,已经不在本应用中了。
  • 比如将任务交给MQ,这个就是异步操作了。因为交给MQ以后,你不必等待结果返回。
  • 当然,如果你调用另外一个应用/进程,另外的一个应用/进程将任务加入任务队列,然后立即返回你成功失败,那这个过程也属于异步任务。这个过程就是MQ做的事情了。。

本篇重点讲述多线程异步任务的执行方式。多进程方式可以查看《SpringBoot入门建站全系列(十七)整合ActiveMq(JMS类消息队列)》和《SpringBoot入门建站全系列(十八)整合RabbitMQ(AMQP类消息队列)》中的消息发送方式。

首发地址:

品茗IT-同步发布

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

二、前言

多线程的异步任务执行有几种方式,还是前面所说的那样,方式虽然不同,但原理是一样的,就是在新线程中执行任务,但是还是要说一下这几种方式。

  • new Thread 普通线程方式执行;
  • ThreadPool线程池,线程使用频繁的时候,减少线程创建回收的开销。实现方式有多种,但是jdk1.5开始支持线程池,就在java.util.concurrent里。
  • Spring提供的@Async注解。其实也是基于线程池。
  • 注意Runnable和Callable在异步任务中的应用,一个不带返回值,一个带返回值而已。

本文是在Springboot环境中测试的。引入spring-boot-starter-web即可。如果不会搭建,可以打开这篇文章看一看《SpringBoot入门建站全系列(一)项目建立》。

在web项目中测试会比较方便,我们利用RequestContextHolder获取ThreadLocal的Request对象来判断线程是否改变了

假设我们要执行的任务是这样的, 为了异步执行AsyncTaskService 中的asyncTask方法:

package com.cff.springbootwork.async.service;import javax.servlet.http.HttpServletRequest;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;@Service
public class AsyncTaskService {private Logger log = LoggerFactory.getLogger(this.getClass());/*** 普通的一方法而已,供异步任务调用*/public void asyncTask() {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();if (requestAttributes != null) {HttpServletRequest curRequest = ((ServletRequestAttributes) requestAttributes).getRequest();log.info("异步任务开始执行,当前请求属性test为:{}", curRequest.getAttribute("test"));} else {log.info("异步任务不是同一个线程了,别想拿ThreadLocal对象了");}try {Thread.sleep(5000);log.info("我是异步任务,我就是个打印!");} catch (InterruptedException e) {e.printStackTrace();}log.info("5s后异步任务终于执行完成");}}

三、普通线程方式

首先我们在Request中塞入一个值,后面用来获取判断是否是主线程。

然后用new Thread新建线程执行异步任务。

我们将逻辑写在AsyncService中,来调用AsyncTaskService的asyncTask方法。

AsyncService:

/*** 测试new Thread 异步任务*/public void asyncThread() {log.info("开始执行任务");HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("请求属性test为:{}", request.getAttribute("test"));Thread thread1 = new Thread(new Runnable() {public void run() {asyncTaskService.asyncTask();}});thread1.start();HttpServletRequest afterRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("任务提前执行完成,开始返回,请求属性test为:{}", afterRequest.getAttribute("test"));}

结果如下:

2019-08-08 16:39:50,516 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:39:50,517 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:39:50,522 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd
2019-08-08 16:39:50,530 [Thread-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务不是同一个线程了,别想拿ThreadLocal对象了
2019-08-08 16:39:55,530 [Thread-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:39:55,530 [Thread-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成
  • 首先获取下request的test属性,能获取到;
  • 执行异步任务,拿不到request对象了,因为不是同一个线程,ThreadLocal没有。
  • 程序直接返回了,异步任务5s以后才执行完。

四、线程池方式

首先我们在Request中塞入一个值,后面用来获取判断是否是主线程。

然后将异步任务扔给线程池执行。

这里我们分别使用Runnable和Callable来测试下。

先建立一个线程池:

package com.cff.springbootwork.async.service;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;import org.springframework.stereotype.Service;@Service
public class ThreadPoolService {private ExecutorService executor;@PostConstructpublic void init() {
//      executor = new ThreadPoolExecutor(20, 30, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(),
//              new ThreadPoolExecutor.AbortPolicy());executor = Executors.newCachedThreadPool();}public void execute(Runnable task) {executor.execute(task);}public <T> Future<T> submit(Callable<T> task) {return executor.submit(task);}@PreDestroypublic void shutdown() {executor.shutdown();}
}

4.1 Runnable普通异步任务

我们将逻辑写在AsyncService中,来调用AsyncTaskService的asyncTask方法。

AsyncService:

/*** 测试 线程池 异步任务*/public void asyncThreadPool() {log.info("开始执行任务");HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("请求属性test为:{}", request.getAttribute("test"));threadPoolService.execute(new Runnable() {public void run() {asyncTaskService.asyncTask();}});HttpServletRequest afterRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("任务提前执行完成,开始返回,请求属性test为:{}", afterRequest.getAttribute("test"));}

结果如下:

2019-08-08 16:44:19,136 [http-nio-8080-exec-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:44:19,136 [http-nio-8080-exec-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:44:19,137 [http-nio-8080-exec-4][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd
2019-08-08 16:44:19,138 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务不是同一个线程了,别想拿ThreadLocal对象了
2019-08-08 16:44:24,140 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:44:24,140 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成
  • 首先获取下request的test属性,能获取到;
  • 执行异步任务,拿不到request对象了,因为不是同一个线程,ThreadLocal没有。
  • 程序直接返回了,异步任务5s以后才执行完。

和new Thread方式一样。唯一区别就是它是线程池,线程可以回收,线程使用频繁的时候,减少线程创建回收的开销。

4.2 Callable异步任务返回结果

我们将逻辑写在AsyncService中,来调用AsyncTaskService的asyncTask方法。

AsyncService:

/*** 测试 线程池 异步任务 Future回调*/public void asyncFuturePool() {log.info("开始执行任务");HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("请求属性test为:{}", request.getAttribute("test"));Callable<String> callable = new Callable<String>() {@Overridepublic String call() throws Exception {asyncTaskService.asyncTask();return "1111";}};Future<String> future = threadPoolService.submit(callable);try {// future.get(); // 阻塞函数,如果直接用,它就一直阻塞,就不是异步了。if (future.isDone()) {log.info("这么快就完成了?不可能!");String result = future.get();log.info("任务结果为:{}", result);}} catch (InterruptedException e1) {e1.printStackTrace();} catch (ExecutionException e1) {e1.printStackTrace();}HttpServletRequest afterRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("任务提前执行完成,开始返回,请求属性test为:{}", afterRequest.getAttribute("test"));}

如果注掉future.get(),结果如下:

2019-08-08 16:46:44,001 [http-nio-8080-exec-7][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:46:44,002 [http-nio-8080-exec-7][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:46:44,003 [http-nio-8080-exec-7][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd
2019-08-08 16:46:44,003 [pool-1-thread-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务不是同一个线程了,别想拿ThreadLocal对象了
2019-08-08 16:46:49,003 [pool-1-thread-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:46:49,003 [pool-1-thread-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成

这个过程和4.1完全一样了。

如果不注掉future.get(),结果如下:

2019-08-08 16:48:02,472 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:48:02,472 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:48:02,478 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务不是同一个线程了,别想拿ThreadLocal对象了
2019-08-08 16:48:07,478 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:48:07,478 [pool-1-thread-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成
2019-08-08 16:48:07,478 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 这么快就完成了?不可能!
2019-08-08 16:48:07,478 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务结果为:1111
2019-08-08 16:48:07,478 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd

虽然拿到了结果,也使用了多线程,但是这个过程变成同步了,因为主线程一直等待另外一个线程执行完才执行下一步。

五、Spring的@Async注解方式

@Async注解的方法,不能和调用方法在同一个类中,因为它是动态代理调用的。同一个类中动态代理个毛啊。。

首先要使用注解@EnableAsync开启异步执行功能。

package com.cff.springbootwork.async.config;import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {}

5.1 同一个类中测试

我们将逻辑写在AsyncService中,新建个方法asyncTaskAnnotation,加上@Async注解并调用AsyncTaskService的asyncTask方法,进行测试。

AsyncService:

/*** 测试 @Async 对异步任务的支持*/@Asyncpublic void asyncTaskAnnotation() {asyncTaskService.asyncTask();}/*** 测试 Spring的@Async 对异步任务的支持, 同一个类内的方法不能实现异步*/public void asyncSpringAnnotationOne() {log.info("开始执行任务");HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("请求属性test为:{}", request.getAttribute("test"));asyncTaskAnnotation();HttpServletRequest afterRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("任务提前执行完成,开始返回,请求属性test为:{}", afterRequest.getAttribute("test"));}

测试结果如下:

2019-08-08 16:54:09,957 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:54:09,957 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:54:09,962 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务开始执行,当前请求属性test为:asdasd
2019-08-08 16:54:14,962 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:54:14,962 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成
2019-08-08 16:54:14,962 [http-nio-8080-exec-1][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd

可以看出,异步任务竟然可以拿到request的test属性了,表明这压根就是同一个线程,@Async无效。

5.2 不同类中测试

我们将逻辑写在AsyncService中,在AsyncTaskService新建个方法asyncTaskAnnotation,加上@Async注解并调用asyncTask方法,进行测试。

AsyncService:

/*** 测试 Spring的@Async 对异步任务的支持, 不同类的方法可以实现异步*/public void asyncSpringAnnotationMuti() {log.info("开始执行任务");HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("请求属性test为:{}", request.getAttribute("test"));asyncTaskService.asyncTaskAnnotation();HttpServletRequest afterRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();log.info("任务提前执行完成,开始返回,请求属性test为:{}", afterRequest.getAttribute("test"));}

测试结果如下:

2019-08-08 16:56:50,964 [http-nio-8080-exec-6][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 开始执行任务
2019-08-08 16:56:50,964 [http-nio-8080-exec-6][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 请求属性test为:asdasd
2019-08-08 16:56:50,964 [http-nio-8080-exec-6][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncService] 任务提前执行完成,开始返回,请求属性test为:asdasd
2019-08-08 16:56:50,965 [SimpleAsyncTaskExecutor-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 异步任务不是同一个线程了,别想拿ThreadLocal对象了
2019-08-08 16:56:55,965 [SimpleAsyncTaskExecutor-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 我是异步任务,我就是个打印!
2019-08-08 16:56:55,965 [SimpleAsyncTaskExecutor-2][IP:|USER:][INFO  com.cff.springbootwork.async.service.AsyncTaskService] 5s后异步任务终于执行完成

可以看出,异步任务拿不到request对象了,@Async正常使用。

六、 测试类及Service完整代码

AsyncRest:

package com.cff.springbootwork.async.web;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import com.cff.springbootwork.async.service.AsyncService;/*** 测试乐异步任务* * @author fufei**/
@RestController
@RequestMapping("/async")
public class AsyncRest {@AutowiredAsyncService asyncService;@RequestMapping(value = "/thread", method = { RequestMethod.GET })public String thread(HttpServletRequest request) {request.setAttribute("test", "asdasd");asyncService.asyncThread();return "0000";}@RequestMapping(value = "/pool", method = { RequestMethod.GET })public String pool(HttpServletRequest request) {request.setAttribute("test", "asdasd");asyncService.asyncThreadPool();return "0000";}@RequestMapping(value = "/future", method = { RequestMethod.GET })public String future(HttpServletRequest request) {request.setAttribute("test", "asdasd");asyncService.asyncFuturePool();return "0000";}@RequestMapping(value = "/springOne", method = { RequestMethod.GET })public String springOne(HttpServletRequest request) {request.setAttribute("test", "asdasd");asyncService.asyncSpringAnnotationOne();return "0000";}@RequestMapping(value = "/springMuti", method = { RequestMethod.GET })public String springMuti(HttpServletRequest request) {request.setAttribute("test", "asdasd");asyncService.asyncSpringAnnotationMuti();return "0000";}
}

AsyncService:

AsyncTaskService:

详细完整的代码,可以访问品茗IT-博客《SpringBoot入门建站全系列(二十二)异步任务执行的几种方式》进行查看

品茗IT-博客专题:https://www.pomit.cn/lecture.html汇总了Spring专题、Springboot专题、SpringCloud专题、web基础配置专题。

快速构建项目

Spring组件化构建

SpringBoot组件化构建

SpringCloud服务化构建

喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot使用吧!

b2cb0c2a0fbe527e872ac0d02d7ff757.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_819837.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站推荐:The Python Challenge 第一个编程解谜站点

The Python Challenge是一个过关式的解谜站点&#xff0c;使用的是经典在线解谜站点Not Pr0n的模式&#xff1a;根据提示找出下一关的网页地址。和Not Pr0n不同的是&#xff0c;在每一关里你都需要编写程序来寻找答案。虽然这个解谜站点的名字叫做Python Challenge&#xff0c;…

网站推荐:blackflip 基于Flash的web 2.0解谜游戏站

blackflip是一个有趣的智力游戏。在每一个关卡里&#xff0c;你需要画一条不自交的路线&#xff0c;这条路线经过的所有格子都将会反色&#xff0c;游戏的目标就是要让反色后同一行的所有格子恰好都同色。游戏规则很简单&#xff0c;但有一些关卡特别费脑子。我很喜欢这个游戏的…

网站页面左右_诠网科技|杭州网站建设成本都用在了哪里呢?

杭州网站建设成本都用在了哪里呢&#xff1f;企业到底为什么要做一个自己的网站呢&#xff1f;企业建站不是为了赶一时的潮流&#xff0c;企业建站只有把网络推广技术同企业的管理系统、服务系统和商务系统紧密地集成&#xff0c;才能发挥企业网站优化的作用。不过企业网站建设…

网站推荐:archimy.com 在线函数图象绘制

archimy.com是刚建立的一个在线数学工具&#xff0c;给人的第一印象非常不错。这个网站可以在线绘制出2D和3D的函数图象&#xff0c;支持参数方程&#xff0c;支持三角函数、反三角函数、对数、绝对值、取整、较大、较小等多种函数。你可以设定函数图象的绘制范围和取样步长。绘…

html 5 浏览器兼容性测试网站

为什么80%的码农都做不了架构师&#xff1f;>>> 浏览器兼容性测试网站 http://caniuse.com/ 转载于:https://my.oschina.net/doz/blog/497347

SEO细分领域项目汇总

因为自己也在从事网络营销业务&#xff0c;所以会经常分析一些的营销手法&#xff0c;今天卢松松整理了一下在百度体系下SEO的一些业务。本文介绍了一些SEO项目&#xff0c;里面有一些细节&#xff0c;仔细思考一下&#xff0c;也许你会发现新项目。(重点看第三条)1&#xff0c…

服务器 网站 未备案,域名解析到未备案服务器

域名解析到未备案服务器 内容精选换一换公网域名解析是基于Internet网络的域名解析过程&#xff0c;可以把人们常用的域名(如www.example.com)转换成用于计算机连接的IP地址(如1.2.3.4)。公网域名解析支持通过直接在浏览器中输入域名&#xff0c;访问网站或Web应用程序。云解析…

大型网站数据库架构分析

涉及知识点&#xff1a; 1&#xff0c;主从复制&#xff0c;读写分离 对主库修改数据&#xff0c;查询使用从库。一主多从&#xff0c;来降低数据库读取压力。2&#xff0c;分库分表 查看详情根据实体业务来分库&#xff0c;分表。如&#xff0c;根据数据的活跃性&#xff0c…

python 判断 网站是否是动态_错过金三银四,但是你不能错过这份Python面试大全...

最近听说很多同学在刷面试题&#xff0c;所以这里给大家整理了一下&#xff0c;现在企业面试的一些重灾区&#xff0c;我从大量的题目中总结了很多的知识&#xff0c;同时也对一些题目进行拓展了&#xff0c;但是在看了网上的大部分面试题不是很满意&#xff0c;一个是有些部分…

html 分页 惰性加载,懒加载实现的分页网站footer自适应

最近在做手机端&#xff0c;发现下拉刷新和上拉加载的jq控件很少而且自我感觉不好用&#xff0c;比如iscroll之类……然后自己写了个懒加载的&#xff0c;也很简单&#xff0c;最基础的代码【不喜勿喷&#xff0c;但蛮实用的】wap手机端懒加载分页&#xff1a;用之前先引用下jq…

怎么看网站调用了哪些js_SEO技术-蜘蛛评判网站内容质量高低看哪些细节

“内容为王”这句话是SEO站长一直以来不离口的一句话&#xff0c;从中反映出网站内容是网站排名优化的重中之重。网站内容的质量高低也是影响着蜘蛛评判网站打分的重要因素&#xff0c;一个高质量内容的页面一定是比低质量内容页面收录好&#xff0c;这是毋庸置疑的。对于SEO来…

FOX新剧Fringe #038; 官方网站上的一个小谜题

知道4400被砍后&#xff0c;我郁闷了很久&#xff0c;这个暑假又没啥值得期待的了。随之而来的消息让我整个人立即又振奋起来&#xff1a;今年9月FOX将要推出一部科幻惊悚新剧Fringe。FOX的这个新剧显然是下了血本的&#xff0c;从它的预告片和宣传力度就看得出来。据某些看了第…

注册域名与SEO搜索优化

为什么80%的码农都做不了架构师&#xff1f;>>> 注册域名应该考虑哪些对SEO和网站运营影响 域名是互联网公司和个人网站的无形资产之一&#xff0c;网站的内容、流量都有域名有关系。 一个好的域名对SEO搜索引擎优化和网站运营都有一定的影响。 1、域名的后缀 …

Azure 网站上的 Java

&#xfeff;&#xfeff;编辑人员注释&#xff1a;本文章由Windows Azure 网站团队的项目经理Chris Compy 撰写。 Microsoft 已推出针对 Azure 网站上基于 Java 的网站的支持。此功能旨在通过Azure 网站的可管理性和轻松扩展选项满足许多常见Java 场景的需求。 门户 UX 中的内…

20个以矩形元素为特色的创意网站设计作品

向社会大众呈现网站内容的方式有很多&#xff0c;这里推荐一组应用方形和矩形元素的网站。人们通常习惯把方形块用于作品集和电子商务网站&#xff0c;因为它是组织和展示作品&#xff0c;如设计&#xff0c;摄影&#xff0c;产品等正方形和长方形元素的最佳方法之一&#xff0…

幻音网站服务器出错,关于页面莫名其妙出现空白的编码错误

在很久之前就发现了这个问题&#xff0c;一般正常的页面是GBK或UTF8的编码格式&#xff0c;但是有些时候会变成一种叫UTF8BOM的编码&#xff0c;一般是不怎么注意的。然而在调试的时候&#xff0c;咦&#xff1f;这怎么多了一块&#xff0c;然后查看源代码&#xff0c;噢&#…

JAVA程序员的学习网站(3)

2019独角兽企业重金招聘Python工程师标准>>> 1.tomcat:http://tomcat.apache.org/2.solr:https://lucene.apache.org/solr/3.ant:http://ant.apache.org/4.maven:http://search.maven.org/ 转载于:https://my.oschina.net/Tsher2015/blog/668208

java物流网站的设计与实现

物流信息网主要用于实现网上自主物流&#xff0c;基本功能包括&#xff1a;登录、查询、时效查询、价格查询、注册等。本系统结构如下&#xff1a; &#xff08;1&#xff09;普通用户&#xff1a; 登录&#xff1a;账号、密码&#xff1b; 查询&#xff1a;通过快递编号进行查…

基于java的赛北村旅游网站的设计与实现

塞北村镇旅游网站设计主要用于实现旅游景点信息管理&#xff0c;基本功能包括&#xff1a;主界面模块设计&#xff0c;用户注册模块&#xff0c;旅游景点模块&#xff0c;酒店预订模块&#xff0c;后台管理模块等。本系统结构如下&#xff1a; &#xff08;1&#xff09;主界模…

基于java的赛北村旅游网站的设计与实现

塞北村镇旅游网站设计主要用于实现旅游景点信息管理&#xff0c;基本功能包括&#xff1a;主界面模块设计&#xff0c;用户注册模块&#xff0c;旅游景点模块&#xff0c;酒店预订模块&#xff0c;后台管理模块等。本系统结构如下&#xff1a; &#xff08;1&#xff09;主界模…