SpringBoot线程池的使用
2019-08-01 22:29
1811 查看
第一步、配置线程池
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<Integer> 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,线程将被终止。这样,线程池可以动态的调整池中的线程数。
相关文章推荐
- 深入学习springboot线程池的使用和扩展
- springboot线程池的配置使用
- springboot线程池的使用和扩展
- 转载Spring Boot线程池的使用
- springboot线程池的使用和扩展(转)
- Spring中使用JdbcTemplate操作数据库
- maven 使用assembly plugin 打包报Unable to locate Spring NamespaceHandler for XML schema namespace
- spring详解:使用Spring-Test对Spring框架进行单元测试
- 使用Spring中Src下 -context.xml : 用资源文件夹保存数据库的链接信息 并在配置文件里读取
- spring使用@ExceptionHandler、@ControllerAdvice统一异常处理
- Spring中PropertyPlaceholderConfigurer的使用
- maven构建使用Spring执行定时任务
- Spring配置文件<context:property-placeholder>标签使用漫谈
- 疯狂Spring Cloud连载(22)Web项目中使用Zuul
- Spring:使用动态工厂降低耦合度
- 使用spring过程中遇到:小问题
- 透彻的掌握 Spring 中@transactional 的使用
- Spring、Spring事务详解;使用XML配置事务
- Spring boot项目 使用ip+port+contextPath进行访问的时候会直接显示出项目中的一些接口信息和相关数据
- spring-security-jwt使用简介