AQS在Worker中的应用
我对这个上锁一直搞不懂,虽然有注释说是允许中断啥的,但是还是一头雾水,就打算直接看代码分析。第一眼看到这个lock的时候,我就吓到了。啥,一上锁,多个线程不是就要同步排队了嘛,而且也没这必要啊。看清楚了才知道,锁来自于方法参数Worker,也就是说,每个线程请求的同步锁都是各自的Worker的锁,故不存在这些个线程竞争一个锁的情况。那问题又来了,我自己的锁,又没人跟我抢,犯得着每做一个任务都上锁吗?
注释不是说了吗,允许中断,那肯定跟中断有关,朝这个方向去找啊。当然,我当时并没有这样去找,而是机缘巧合,看到ThreadPoolExecutor其他代码的时候突然意识到的。
我先看到了shutdown方法,发现有中断空闲Worker的方法。但是在此之前,我并不知道线程池是如何区别Worker空闲和忙碌的,只知道线程池有workers字段用来存储创建的Worker。于是,我就顺着方法查看下去。找到关闭空闲Worker方法的实现。
由上述代码可知,线程池区分Worker是否空闲的方法就是,能否成功获取到Worker的锁。这个锁是独占锁,由前面的代码可知,一旦Worker对应线程获取到任务,就会上锁并开始执行。那这样,w.tryLock()方法将失败,此线程就会被判定为是非空闲线程。而如果线程在获取任务的过程中被阻塞,也就是还没调用w.lock(),那这里的tryLock()将成功获取独占锁,那此线程就被判定为是空闲线程而被中断。
注:shutdown()方法的语义就是,让已经开始的任务继续做,未开始的终止,把多余的工作线程关闭。其对应的状态是SHUTDOWN
那问题又来了,如何终止已经开始的任务呢?
这里终止已经开始的任务,就是shutdownNow方法要做的。(shutdownNow就是停止所有任务,已经开始也要停止。其对应的状态是STOP)
前面由于无法获取到Worker的锁,故无法通过interruptIdleWorkers方法将其中断。但是ThreadPoolExecutor还提供了interruptWorkers方法,该方法不用获取锁,直接调用Worker的interruptIfstarted方法中断线程。
原文:https://www.cnblogs.com/longfurcat/p/9892395.html