Worker extends AbstractQueuedSynchronizer, 它就是一个运行task的线程,没有task就去queue里去take,它继承AQS是
/** * Class Worker mainly maintains interrupt control state for * threads running tasks, along with other minor bookkeeping. * This class opportunistically extends AbstractQueuedSynchronizer * to simplify acquiring and releasing a lock surrounding each * task execution. This protects against interrupts that are * intended to wake up a worker thread waiting for a task from * instead interrupting a task being run. We implement a simple * non-reentrant mutual exclusion lock rather than use * ReentrantLock because we do not want worker tasks to be able to * reacquire the lock when they invoke pool control methods like * setCorePoolSize. Additionally, to suppress interrupts until * the thread actually starts running tasks, we initialize lock * state to a negative value, and clear it upon start (in * runWorker). */
英文不怎么会,大概就是保护线程运行task,初始的时候置state为-1.
想了半天,得出:
1, 如果此线程运行task不去拿个排它锁,此时如果出现清理idel线程的行为,方法 interruptIdleWorkers 就不用这行:
if (!t.isInterrupted() && w.tryLock()) {
如果task代码实现里有Thread.sleep或者join等,那就会被中断,task运行没完成。这个应该就是注释里所说避免
"instead interrupting a task being run"的含义。加锁以后线程池shutdown或者resetsize需要interrupt threads需要先
拿到锁。
2, 有人问为啥不直接用ReentrantLock,这个回答也是解释代码注释。
https://stackoverflow.com/questions/42189195/why-threadpoolexecutorworker-extends-abstractqueuedsynchronizer
很奇怪怎么thread自己怎么会有分身术,在专注与运行task的时候怎么会去调用setCorePoolSize呢?
protected void beforeExecute(Thread t, Runnable r) { }
这方法在ThreadPoolExecutor里, 可以重写, 它在task.run 之前被调用,故还是有这种机会的。afterExecute同理。