面试官:你给我说一下线程池里面的几个锁吧( 四 )


如果你还没反应过来是怎么回事的话,我给你看一下 ReentrantLock 里面的重入逻辑:
你看到了吗,有一个累加的过程 。
释放锁的时候,又有一个与之对应的递减的过程,减到 0 就是当前线程释放锁成功:
而上面的累加、递减的逻辑在 worker 类里面通通是没有的 。
那么问题又来了:如果是可以重入的,会发生什么呢?
目的还是很前面一样:不想打断正在执行任务的线程 。
同时注释里面提到了一个方法:setCorePoolSize 。
你说巧不巧,这个方法我之前写线程池动态调整的时候重点讲过呀:
可惜当时主要讲 delta 0 里面的的逻辑去了 。
现在我们看一下我框起来的地方 。
workerCountOf(ctl.get()) corePoolSize 为 true 说明什么情况?
说明当前的 worker 的数量是多于我要重新设置的 corePoolSize,需要减少一点 。
怎么减少呢?
调用 interruptIdleWorkers 方法 。
这个方法我们前面刚刚分析了,我再拿出来一起看一下:
里面有个 tryLock,如果是可以重入的,会发生什么情况?
是不是有可能把正在执行的 worker 给中断了 。
这合适吗?
好了,注释上的最后一句话:
这句话就是说为了在线程真正开始运行任务之前,抑制中断 。所以把 worker 的状态初始化为负数(-1) 。
大家要注意这个:and clear it upon start (in runWorker).
在启动的时候清除 it,这个 it 就是值为负数的状态 。
老爷子很贴心,把方法都给你指明了:in runWorker.
所以你去看 runWorker,你就知道为什么这里上来先进行一个 unLock 操作,后面跟着一个 allow interrupts 的注释:
因为在这个地方,worker 的状态可能还是 -1 呢,所以先 unLock,把状态刷到 0 去 。
同时也就解释了前面我没有解释的 -1 是哪里来的:
想明白了吗,-1 是哪里来的?
肯定是在启动过程中,执行了 workers.add 方法,但是还没有来得及执行 runWorker 方法的 worker 对象,它们的状态就是 -1 。
最后说一句好了,看到了这里了,点赞安排一个吧 。写文章很累的,需要一点正反馈 。
给各位读者朋友们磕一个了:
【面试官:你给我说一下线程池里面的几个锁吧】

推荐阅读