Executor源码解析及遇到的问题

最近研究了一下Executor源码,其中找到了很好的一篇博文,讲得非常好:https://www.jianshu.com/p/bbcf4921797c

下面我分享几个我学习过程中遇到的几个问题:

 1、Executor中怎样来保证核心线程不会终止呢?

    这个问题首先我们看一下execute(Runnable command)方法中有这么一段:

   

其实这个addWorker(command,true)里面就是添加核心线程,任务的执行就是会在线程添加后直接执行,我们跟踪进入这个addWorker(command,true)方法,里面有这么一段:

这里t.start()就是开始执行任务了,其中t就是所添加的线程,它在worker对象中。接下来我们看一下t的run()方法里面怎么写的:

这里面直接调用的runWorker()方法,所以我们直接看runWorker()方法。里面有这么一段

注意这个getTask()方法,其实重点就在这个getTask()方法里面,这个方法会去任务队列里面获取任务,而我们知道这个任务队列是一个阻塞队列,当有任务时,直接可以获取到任务,这里的while()就会一直执行,如果队列中没有任务,则队列会阻塞(这里我说的是核心线程的情况),此时线程就会被阻塞,所以线程就不会终止。分析了这么多,我们进入getTask()方法看一下:

里面重点看一下这两段,当timed为true的时候,任务队列执行poll(long timeout,TimeUnit unit)方法,如果为false则执行take()方法,这个timed是什么呢,我们注意这里:

// 是否允许核心线程超时或者当前工作线程数是否大于核心线程数
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

(1)allowCoreThreadTimeOut是表示是否允许核心线程超时,也就是说是否允许核心线程超时后终止,如果允许,那timed就会为true,故而就会执行workQueue.poll(keepAlive,TimeUnit.NANOSECONDS)方法,时间到了如果还没有任务,线程就会终止。

(2)如果当前线程数wc大于corePoolSize,那timed也会为true,说明当前线程个数已经大于核心线程个数了,当keepAlive时间到达之后这个多的线程就会终止。

(3)当allowCoreThreadTimeOut为false,并且工作线程数小于核心线程数据,此时timed就会为false,故而就会执行workQueue.take()方法,此时该线程就会处于阻塞状态,直到获取到任务r。

这就是Executor中的保持核心线程不会被终止的策略,说白了其实就是使用阻塞队列的take()方法。

2、源代码中使用workerCountOf(int c)方法计算当前工作线程数,是怎么算的?

这个workerCountOf(int c)方法在框架里面很多地方都调用了,就是计算当前工作线程数,其实里面的c & CAPACITY我是看懂了的,我之所以遇到这个问题其实是我感觉这个c好像永远都会是0。导致我出现这个问题的原因其实就是我看漏了一段代码:

就是这两句,c其实在这个compareAndIncrementWorkerCount()中进行增加处理了。

哈哈,这个问题我也是服了我自己了o(╥﹏╥)o

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值