我知道有关AbstractQueuedSynchronizer的一些细节。 它是一个用于创建状态依赖类或同步器的框架。 但是我没有在ThreadPoolExecutor的Worker中扩展这个类。
private final class Worker extends AbstractQueuedSynchronizer implements Runnable
正如工人阶级的签名所见,事情可以推断出来:
提交新的Runnable / Callable任务时,会创建一个新的Worker对象。
可以将Worker的新对象视为新线程。
addWorker()
方法将添加新工作者(或简称为任务)并自行调用worker.start()
以启动该线程。
Worker类是非静态嵌套类,因此它可以访问ThreadPoolExecutor的所有变量
run()
方法在内部调用runWorker(this)
public void run(){ runWorker(本); }
runWorker()
执行如下的实际任务:
void runWorker(Worker w) {
try {
w.lock();
w.firstTask.run()
} finally {
w.unlock();
}
}
AQS仅用于此锁定和解锁runWorker()方法。 我们不能在这里使用ReentrantLock并保持Worker类简单吗?
同时课程提供有关此的文档,但我无法理解:
此类机会性地将AbstractQueuedSynchronizer扩展为 简化获取和释放围绕每项任务的锁定 执行。这可以防止意图唤醒的中断 一个工作线程等待任务而不是中断任务 正在运行。我们实现了一个简单的非重入互斥锁 而不是使用ReentrantLock,因为我们不希望工作任务 能够在调用池控制方法时重新获取锁 比如setCorePoolSize。
请帮忙
答案 0 :(得分:3)
您的问题的答案在您发布的javadoc的引文中:
我们实现了一个简单的非重入互斥锁而不是 使用ReentrantLock是因为我们不希望工作任务能够 在调用池控制方法时重新获取锁 setCorePoolSize。
这是因为可能正在等待任务的线程由未被锁定表示,即tryLock
为它们返回true
。在这种情况下,如果ReentrantLock
将在这里使用,可能会发生什么:那么可以按照一系列动作进行:
setCorePoolSize
- > interruptIdleWorkers
- > tryLock()
(此处成功!) - > Thread.interrupt
(这名工人的主持人)
会导致工作人员自行中断。