threadpoolexecutor 不执行_JUC之ThreadPoolExecutor实现原理分析

ThreadPoolExecutor工作流程

JDK1.5中引入了线程池,合理地利用线程池能有效的提高程序的运行效率,但不当的使用线程池也会带来致命的危害。作为使用最多的ThreadPoolExecutor,很有必要深入理解的其源码与实现原理。

先看一下ThreadPoolExecutor是如何工作的,暂时不看源码,这样会先有一个比较直观的印象有利于后面深入分析源码。

既然是线程池那么提交任务后一定要创建线程用于执行任务,ThreadPoolExecutor创建线程执行提交任务的流程如下。



0407e8df048a7a6e3e7fb1976e440d71.png



简单介绍一下,一个任务提交给线程池后,线程池创建线程来执行提交任务的流程。

  1. 当提交任务时线程池中的来用执行任务的线程数小于corePoolSize(核心线程数),则线程池利用ThreadFacory(线程工厂)创建线程用于执行提交的任务。否则执行第二2步。
  2. 当提交任务时线程池中的来用执行任务的线程数大于corePoolSize(核心线程数),但workQueue没有满,则线程池会将提交的任务先保存在workQueue(工作队列),等待线程池中的线程执行完其它已提交任务后会循环从workQueue中取出任务执行。否则执行第3步。
  3. 当提交任务时线程池中的来用执行任务大于corePoolSize(核心线程数),且workQueu已满,但没有超过maximunPoolSize(最大线程数),则线程池利用ThreadFacory(线程工厂)创建线程用于执行提交的任务。否则执行4。
  4. 当提交任务时线程池中的来用执行任务大于maximunPoolSize,执行线程池中配置的拒绝策略(RejectedExecutionHanlder)。

下图给出了ThreadPoolExecutor更加直观的整体运行图。图中标注1、2、3、4的分别对应上面分析中的第1、第2、第3、第4步。



6baa959e0a58597bb9ae0a6451785de9.png



结合上图补充几点:

  1. 线程池中创建的用于执行提交任务的线程的引用被Worker对象持有。Worker会去执行提交的任务,如果提交的任务已执行完Worker会循环地从workQueue(即图中的BlockingQueue)中poll或take任务执行。
  2. 主线程调用ThreadPoolExecutor的prestartCoreThread()或prestartAllCoreThreads()方法可以在任务还没有提交到线程池前,先创建用于执行提交任务的Worker,这些Worker将等待任务提交。
  3. 线程池饱和时默认地拒绝策略为AbortPolicy策略,抛出RejectedExecutionException异常,上图中CallerRunsPolicy表达的不是默认地拒绝策略,而是CallerRunsPolicy策略是会将提交的任务(Task)交给主线程执行。即主线程调用Task.run()方法。

ThreadPoolExecutor源码分析

fc0d5cb0a6e95023f226a043d285e059.png

ThreadPoolExecutor的UML类图如上图,其中Executor提供最基础的任务执行的抽象void execute(Runnable command)方法,而ExecutorService在其基础上扩展的管理线程池的一些方法shutdown()、shutdownNow()、isShutdown() 与isTerminated()等,同时增加了用三个重载的submit方法,用于获取任务的执行结果。submit可以提交Callable类型的任务,也可提交Runnable类型的任务。AbstractExecutorService类提供了newTaskFor将提交的Callable与Runnable类型任务转为FutureTask,同时提供了sumbit与invoke的默认实现,具体的任务执行逻辑交由子类ThreadPoolExecutor的execute方法。不管是调用submit还是execute的提交的任务,最终都交由ThreadPoolExecutor的execute方法执行。

execute方法是分析ThreadPoolExecutor源码的入口。

分析execute方法前先看一下ThreadPoolExecutor里面的核心变量与类。

//线程池状态与线程池中有效线程数控制变量,AtomicInteger变量的高3位用于//保存线程池状态,低29位用于保存线程池中有效线程数。 //程线程对应状态如下:// 1、RUNNING: 运行中,接收新的任务或处理队列中的任务 值为-536870912// 2、SHUTDOWN: 关闭,不再接收新的任务,但会处理队列中的任务 值为0// 3、STOP: 停止,不再接收新的任务,也不处理队列中的任务,并中断正在处理的任务 值为536870912// 4、TIDYING:  所有任务已结束,队列大小为0,转变为TIDYING状态的线程将会执行terminated() hook 方法 值为1073741824// 5、TERMINATED: 结束,terminated() 已被执行完 值为1610612736private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

与ctl变量有关的操作方法

//获取线程池的运行状态runState//CAPACITY 二进制值为: 00011111111111111111111111111111//~CAPACITY 按位取反为:11100000000000000000000000000000//ctl&~CAPACITY 低29全为0,得到高3位即线程池的runStateprivate static int runStateOf(int c)     { return c & ~CAPACITY; }//获取线程池中有效的线程数private static int workerCountOf(int c)  { return c & CAPACITY; }//根据runState与workerCount计算出ctl的值private static int ctlOf(int rs, int wc) { return rs | wc; }//判断线程池是否处于运行中private static boolean isRunning(int c) {return c < SHUTDOWN;}

其它核心成员变量

//工作队列,提交任务超过corePoolSize时,任务被保证在workQueue中private final BlockingQueue workQueue;//处理wokers的锁private final ReentrantLock mainLock = new ReentrantLock(); //工作作线程集合private final Hash workers = new HashSet(); //用于支持awaitTermination方法的条件private final Condition termination = mainLock.newCondition(); //曾经创建过的最大工作线程数private int largestPoolSize;//线程池中已完成的总任务数private long completedTaskCount;//线程池创建执行提交任务对应线程时采用的线程工厂private volatile ThreadFactory threadFactory;//线程池饱和时,拒绝策略private volatile RejectedExecutionHandler handler;//allowCoreThreadTimeOut为true时,无任务时情况下核心线程允许存活时间;//线程池中超过核心线程数,那部分工作线程,无任务时情况下核心线程允许存活时间。private volatile long keepAliveTime;//核心工作线程是以超时的方式还是阻塞的方式尝试从workQueue队列里面获取任务,//当以超时的方式获取时,如果在指定时间内还没有获取到任务工作线程run方法将执//行完毕,对应工作线程被GC回收private volatile boolean allowCoreThreadTimeOut;//线程池中核心工作线程数private volatile int corePoolSize;//线程池中最大工作线程数priv
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值