扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
第一步、配置线程池
莱芜网站制作公司哪家好,找创新互联建站!从网页设计、网站建设、微信开发、APP开发、响应式网站设计等网站项目制作,到程序开发,运营维护。创新互联建站自2013年起到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联建站。
package com.kyy.springboot.pool;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@Configuration
public class GlobalConfig {
@Bean
public ThreadPoolTaskExecutor defaultThreadPool(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//核心线程数量
threadPoolTaskExecutor.setCorePoolSize(2);
//最大线程数量
threadPoolTaskExecutor.setMaxPoolSize(5);
//队列中最大任务数
threadPoolTaskExecutor.setQueueCapacity(2);
//线程名称前缀
threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-");
//当达到最大线程数时如何处理新任务
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//线程空闲后最大存活时间
threadPoolTaskExecutor.setKeepAliveSeconds(60);
//初始化线程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
第二步、创建Service
package com.kyy.springboot.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@Service
public class BootService {
@Resource(name = "defaultThreadPool")
private ThreadPoolTaskExecutor poolTaskExecutor;
@Async
public void testPool() {
System.out.println("线程名称:" + Thread.currentThread().getName());
}
public void testNoPool() {
System.out.println("线程名称:" + Thread.currentThread().getName());
}
public int testPoolTaskExecutor(int n) throws InterruptedException, ExecutionException {
CountDownLatch countDownLatch = new CountDownLatch(n);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int sum = 0;
for (int i = 1; i <= n; i++) {
final int index = i;
final Future future = poolTaskExecutor.submit(() -> {
Thread.sleep(5000);
System.out.println(simpleDateFormat.format(new Date())+" "+Thread.currentThread().getName() + " 执行 " + index);
countDownLatch.countDown();
return 1;
});
}
countDownLatch.await();
return sum;
}
}
第三步:创建Controller
package com.kyy.springboot.controller;
import com.kyy.springboot.service.BootService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutionException;
/**
* Auth: zhouhongliang
* Date:2019/8/1
*/
@RestController
public class PoolController {
@Autowired
private BootService bootService;
@RequestMapping("/pool")
public String pool(){
for (int i=0;i<100;i++){
bootService.testPool();
}
return "pool test";
}
@RequestMapping("/poolTask/{n}")
public String poolTask(@PathVariable int n){
long startTime = System.currentTimeMillis();
try {
bootService.testPoolTaskExecutor(n);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
return "poolTask test "+(endTime-startTime)/1000+" 秒";
}
}
第四步:创建启动类
package com.kyy.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 启动程序
* @Auther:zhouhongliang
* @Date:2019/7/30
* @Description:
*/
@SpringBootApplication
@EnableAsync
public class SpringBootDemo {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo.class,args);
}
}
总结:线程池配置说明
1、属性字段说明
corePoolSize:线程池维护线程的最少数量
keepAliveSeconds:允许的空闲时间
maxPoolSize:线程池维护线程的最大数量
queueCapacity:缓存队列
rejectedExecutionHandler:对拒绝task的处理策略
2、 execute(Runable)方法执行过程
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maxPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maxPoolSize,那么通过handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流