线程池

线程池

 

 

Executors 封装 线程池(不推荐使用)

直接使用ThreadPoolExecutor ,根据业务需求灵活配置,避免OOM发生的风险。

 1  /**
 2          * 可缓存线程池
 3          * 同时执行的最大线程数是Integer.MAX_VALUE,是高度可伸缩的线程池。可能发生OOM异常。<br/>
 4          * 线程空闲时间60秒,工作线程处于空闲状态,可以回收工作线程复用。(threadlocal在线池复用的场景,要注意,容易产生脏数据)<br/>
 5          * 如果任务数持续增加,没有可复用的工作线程,将不断的创建新线程处理任务。
 6          */
 7         Executors.newCachedThreadPool();
 8         ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
 9                 20L, TimeUnit.MICROSECONDS,
10                 new SynchronousQueue<Runnable>(), new MyThreadFactory());
11 
12 
13         /**
14          * 固定大小线程池<br/>
15          * newFixedThreadPool核心线程数和同时执行最大线程数相等,并且固定一个数,不存在空闲线程,空闲线程没有任何作用,空闲时间设置为零。<br/>
16          * newSingleThreadExecutor核心线程数和同时执行最大线程数为一,保证FIFO执行所有任务。<br/>
17          * 无界队列(队列最大为Integer.MAX_VALUE),瞬间请求过大,会有OOM风险。
18          *
19          */
20         Executors.newFixedThreadPool(2, new MyThreadFactory());
21         Executors.newSingleThreadExecutor(new MyThreadFactory());
22         threadPoolExecutor = new ThreadPoolExecutor(2, 2,
23                 0L, TimeUnit.MILLISECONDS,
24                 new LinkedBlockingQueue<Runnable>(),
25                 new MyThreadFactory());
26 
27         /**
28          * 周期和定时线程池<br/>
29          * 同时执行的线程最大为Integer.MAX_VALUE 存在OOM风险。可以定时和周期执行任务。
30          *
31          */
32         Executors.newScheduledThreadPool(2);
33 
34         /**
35          *
36          * 并行度线程池<br/>
37          *
38          * 使用多个队列,并行度默认为cpu数量。
39          *
40          *
41          */
42         Executors.newWorkStealingPool();

 

 

 

ThreadPoolExecutor  构造器参数

 

 1  /**
 2      * 线程池<br/>
 3      * 线程池ThreadPoolExecutor的参数使用说明<br/>
 4      * {@code corePoolSize}核心线程数,一直维持在线程池中,即使他们是空闲的,除非设置了 {@code allowCoreThreadTimeOut}<br/>
 5      * <p>
 6      * {@code maximumPoolSize}最大线程数,线程池中允许的最大线程数。最大线程数大于等于核心线程数。<br/>
 7      * <p>
 8      * {@code keepAliveTime} 空闲线程存活时间, 当线程数大于核心线程时,这个时间是空闲线程终止之前等待新的任务的最大时间 。<br/>
 9      * <p>
10      * {@code unit} 空闲线程存活时间的单位<br/>
11      * <p>
12      * {@code workQueue} 工作队列,当工作线程大于核心线程时,新的任务加入工作队列中。<br/>
13      * <p>
14      * {@code threadFactory} 线程工厂,线程池通过线程工厂创建新的线程。<br/>
15      * <p>
16      * {@code handle} 拒绝策略,当达到最大线程数也就是达到线程边界和队列容量最大值时,会用到拒绝策略。<br/>
17      */

 

 

 

 

ThreadPoolExecutor execute执行过程
 1 /**
 2  *  ThreadPoolExecutor execute
 3  */
 4 public void execute(Runnable command) {
 5     //判空
 6     if (command == null)
 7         throw new NullPointerException();
 8     //获取执行器计数
 9     int c = ctl.get();
10     //活动线程与核心线程比较,小于侧创建新的线程。
11     if (workerCountOf(c) < corePoolSize) {
12         //添加任务
13         if (addWorker(command, true))
14             //添加成功退出
15             return;
16         c = ctl.get();
17     }
18 
19     //如果执行器未关闭,添加到队列中
20     if (isRunning(c) && workQueue.offer(command)) {
21         int recheck = ctl.get();
22         //如果执行器关闭,删除队列
23         if (! isRunning(recheck) && remove(command))
24             //调用拒绝策略
25             reject(command);
26         //无活动线程,创建新的线程
27         else if (workerCountOf(recheck) == 0)
28             addWorker(null, false);
29     }
30     //无法创建新的任务
31     else if (!addWorker(command, false))
32         //调用拒绝策略
33         reject(command);
34 }

 

ThreadPoolExecutor RejectedExecutionHandler 拒绝策略

根据业务需求选择合适的拒绝策略,如果ThreadPoolExecutor自带的四种拒绝策略无法满足需求,也可以实现RejectedExecutionHandler接口自定义拒绝策略。

 1 public static class CallerRunsPolicy implements RejectedExecutionHandler {
 2         public CallerRunsPolicy() {
 3         }
 4         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
 5             //执行器没有关闭,则直接调用任务的run方法。
 6             if (!e.isShutdown()) {
 7                 r.run();
 8             }
 9             //执行器关闭,抛弃任务。
10         }
11     }
12     public static class AbortPolicy implements RejectedExecutionHandler {
13         public AbortPolicy() {
14         }
15         /**
16          * 直接抛出RejectedExecutionException这个异常。
17          */
18         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
19             throw new RejectedExecutionException("Task " + r.toString() +
20                     " rejected from " +
21                     e.toString());
22         }
23     }
24     public static class DiscardPolicy implements RejectedExecutionHandler {
25         public DiscardPolicy() {
26         }
27         /**
28          * 什么也不做直接抛弃任务
29          */
30         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
31         }
32     }
33     public static class DiscardOldestPolicy implements RejectedExecutionHandler {
34         public DiscardOldestPolicy() {
35         }
36         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
37             //线程执行器未关闭
38             if (!e.isShutdown()) {
39                 //删除队列最老的任务
40                 e.getQueue().poll();
41                 //把任务交给执行器执行。
42                 e.execute(r);
43             }
44             //线程执行器关闭,直接抛弃任务。
45         }
46     }

posted on 2019-12-30 11:38  seesea_bky  阅读(142)  评论(0)    收藏  举报