当前位置:   article > 正文

java线程池ThreadPoolExecutor和ThreadPoolTaskExecutor_threadpooltaskexecutor threadpoolexecutor

threadpooltaskexecutor threadpoolexecutor

前言

1、使用线程池有哪些好处

  • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

2、内存溢出问题

线程池ThreadPoolExecutor和ThreadPoolTaskExecutor的父类不都是Executor吗?那为什么不用Executors去创建线程池呢?

首先来看看Executors大部分方法多数只定义了核心线程数和ThreadFactory, 其他的线程池核心参数都已经在方法内部定义死了。

可以看到默认阻塞队列用的是无界的LinkedBlockingQueue,可能存在一个致命的问题那就是内存溢出问题。当定义的总线程被沾满了后,那么请求就会被列入阻塞队列中。当处理器条件不好或内存设置不大时。大量请求进来导致阻塞队列的容量过大就只能说是使用不当!!!线程池核心参数需要根据实际情况来定义的。

  1. public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
  2. return new ThreadPoolExecutor(nThreads, nThreads,
  3. 0L, TimeUnit.MILLISECONDS,
  4. new LinkedBlockingQueue<Runnable>(),
  5. threadFactory);
  6. }

而ThreadPoolExecutor(jkd提供)和ThreadPoolTaskExecutor(spring提供)是对基础线程池Executors进行封了装和优化

ThreadPoolExecutor

ThreadPoolExecutor是jkd提供为我们提供的创建线程池实现类。更友好的为开发者提供可扩展性的开发策略

继承关系图

构造方法及参数说明

全参构造方法
  1. public ThreadPoolExecutor(int corePoolSize,
  2. int maximumPoolSize,
  3. long keepAliveTime,
  4. TimeUnit unit,
  5. BlockingQueue<Runnable> workQueue,
  6. ThreadFactory threadFactory,
  7. RejectedExecutionHandler handler)
核心参数说明
  • corePoolSize:核心线程数
  • maximumPoolSize:线程池最大线程数量
  • keepAliveTime:空闲线程存活时间
  • TimeUnit unit:可根据枚举设置(时、分、秒、天)
  • BlockingQueue<Runnable> workQueue:用于缓存任务的阻塞队列。JDK中提供四种工作队列 
队列策略说明
ArrayBlockingQueue基于数组的有界阻塞队列,如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
LinkedBlockingQueue基于链表的无界阻塞队列,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,因此使用该工作队列时,参数maxPoolSize没有作用。
SynchronousQuene一个不缓存任务的有界阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
PriorityBlockingQueue具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
  • ThreadFactory:线程工厂 创建新线程时使用的工厂类,可以设置线程是否为守护线程,设置线程名字。
  • RejectedExecutionHandler handler:线程池满后拒绝策略,JDK中有四种默认实现
拒绝策略说明
CallerRunsPolicy线程池shutdown的话直接不管,没有shutdown在调用者线程中直接执行被拒绝任务的run方法。
AbortPolicy丢任务,抛出RejectedExecutionException(默认)
DiscardPolicy直接丢任务
DiscardOldestPolicy抛队列头部任务,把这次拒绝的任务加入队列
线程池创建实践(需根据实际情况配置)
  1. public static ThreadPoolExecutor threadPoolExecutorConfig() {
  2. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
  3. 5,
  4. 10, 3000,
  5. TimeUnit.SECONDS,
  6. new ArrayBlockingQueue(100)
  7. , Executors.defaultThreadFactory(),
  8. new ThreadPoolExecutor.AbortPolicy());
  9. return threadPoolExecutor;
  10. }
  11. @Test
  12. public void startFun() {
  13. ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorConfig();
  14. for (int i = 0; i < 10; i++) {
  15. threadPoolExecutor.execute(() -> System.out.println("当前执行的线程:" + Thread.currentThread().getName()));
  16. }
  17. }
 submit和execute

ThreadPoolExecutor执行任务有submitexecute两种方法,这两种方法区别在于

  • submit提供了三种方法有返回值便于异常处理、线程编排,以及提供了不同的线程类型实现方法。
  • execute只提供了一种方法,没有返回值。
  1. //execute
  2. @Test
  3. public void executeStartFun() {
  4. ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorConfig();
  5. for (int i = 0; i < 10; i++) {
  6. if (i == 5) {
  7. threadPoolExecutor.execute(() -> System.out.println("当前执行的线程:" + Thread.currentThread().getName()));
  8. int sum = 1 / 0;
  9. }
  10. threadPoolExecutor.execute(() -> System.out.println("当前执行的线程:" + Thread.currentThread().getName()));
  11. }
  12. }
  13. //submit
  14. @Test
  15. public void submitStartFun() {
  16. ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorConfig();
  17. List<Future> futures = new ArrayList<>();
  18. for (int i = 0; i < 10; i++) {
  19. futures.add(threadPoolExecutor.submit(() -> "当前执行的线程:" + Thread.currentThread().getName()));
  20. }
  21. futures.stream().forEach(future -> {
  22. try {
  23. System.out.println("future的返回值:" + future.get());
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. } catch (ExecutionException e) {
  27. e.printStackTrace();
  28. }
  29. });
  30. }

ThreadPoolTaskExecutor

ThreadPoolTaskExecutor 是spring提供的线程池实现类,基于ThreadPoolExecutor之上进行封装使得方便与整合spring框架

继承关系图

线程池创建实践(需根据实际情况配置)

因为基于ThreadPoolExecutor之上进行封装,上面已经对线程池核心进行了阐述,这里就直接写实践。ThreadPoolExecutor对spring支持所以直接封装成一个Bean.然后要用的时候直接将Bean依赖注入使用就行

  1. @Configuration
  2. @EnableAsync// 开启线程池
  3. public class ThreadPoolConfig {
  4. /**
  5. * 每秒需要多少个线程处理
  6. * tasks/(1/taskcost)
  7. */
  8. private int corePoolSize = 10;
  9. /**
  10. * 线程池维护线程的最大数量
  11. * (max(tasks)- queueCapacity)/(1/taskcost)
  12. */
  13. private int maxPoolSize = 20;
  14. /**
  15. * 缓存队列
  16. * (coreSizePool/taskcost)*responsetime
  17. */
  18. private int queueCapacity = 100;
  19. /**
  20. * 允许的空闲时间
  21. * 默认为60
  22. */
  23. private int keepAlive = 100;
  24. /**
  25. * 配置默认线程池
  26. */
  27. @Bean("defaultThreadPool")
  28. public TaskExecutor defaultThread() {
  29. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  30. //设置核心线程数
  31. executor.setCorePoolSize(corePoolSize);
  32. //设置最大线程数
  33. executor.setMaxPoolSize(maxPoolSize);
  34. //设置队列容量
  35. executor.setQueueCapacity(queueCapacity);
  36. //设置允许的空闲时间(秒)
  37. executor.setKeepAliveSeconds(keepAlive);
  38. //设置默认的线程名称
  39. executor.setThreadNamePrefix("defaultThreadPool-Async");
  40. //设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务
  41. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  42. // 调度器shutdown被调用时等待当前被调度的任务完成
  43. executor.setWaitForTasksToCompleteOnShutdown(true);
  44. // 等待时长
  45. executor.setAwaitTerminationSeconds(60);
  46. return executor;
  47. }

 可以结合@Async使用线程池异步执行

  1. @Component
  2. public class DefaultThreadPoolHandler{
  3. @Async("defaultThreadPool") //异步使用配置好的ThreadPoolTaskExecutor线程池
  4. public void defaultThreadPoolFun() {
  5. System.out.println("defaultThreadPool执行=======================》");
  6. }
  7. }
  8. //后续使用通过@Autowired依赖注入
  9. @Autowired
  10. private DefaultThreadPoolHandler defaultThreadPoolHandler;

 ThreadPoolTaskExecutor死锁问题

死锁问题分析传送门

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/104692
推荐阅读
相关标签
  

闽ICP备14008679号