为什么 ThreadPoolExecutor$Worker 扩展 AbstractQueuedSynchronizer
Why ThreadPoolExecutor$Worker extends AbstractQueuedSynchronizer
我知道一些关于 AbstractQueuedSynchronizer 的细节。
它是一个用于创建状态依赖 classes 或同步器的框架。
但是我没有得到在 ThreadPoolExecutor 的 Worker 中扩展这个 class 的意义。
private final class Worker extends AbstractQueuedSynchronizer implements Runnable
从Workerclass的签名可以看出:
提交新的Runnable/Callable任务时,会创建一个新的Worker对象。
一个新的Worker对象可以认为是一个新线程
addWorker()
方法将添加新的 worker(或只是一个任务)并调用自身 worker.start()
来启动线程。
Worker class是非静态嵌套的class,因此它可以访问ThreadPoolExecutor
的所有变量
run()
Worker class 的方法内部调用 运行Worker(this)
public无效运行(){
运行工人(这个);
}
runWorker()
执行这样的实际任务:
void runWorker(Worker w) {
try {
w.lock();
w.firstTask.run()
} finally {
w.unlock();
}
}
AQS 仅用于运行Worker() 方法的锁定和解锁。
我们不能在这里使用 ReentrantLock 并保持 Worker class 简单吗?
另外 class 提供有关此的文档,但我无法理解:
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.
请帮忙
您的问题的答案在您发布的 javadoc 的引述中:
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.
这是因为 可能正在等待任务的线程未被锁定 ,即 tryLock
returns true
。如果在这里使用 ReentrantLock
,在这种情况下会发生什么情况:那么可能会发生以下一系列操作:
setCorePoolSize
->interruptIdleWorkers
->tryLock()
(此处成功!)-> Thread.interrupt
(该工人的线程)
这会导致 worker 自身中断。
我知道一些关于 AbstractQueuedSynchronizer 的细节。 它是一个用于创建状态依赖 classes 或同步器的框架。 但是我没有得到在 ThreadPoolExecutor 的 Worker 中扩展这个 class 的意义。
private final class Worker extends AbstractQueuedSynchronizer implements Runnable
从Workerclass的签名可以看出:
提交新的Runnable/Callable任务时,会创建一个新的Worker对象。
一个新的Worker对象可以认为是一个新线程
addWorker()
方法将添加新的 worker(或只是一个任务)并调用自身worker.start()
来启动线程。Worker class是非静态嵌套的class,因此它可以访问ThreadPoolExecutor
的所有变量
run()
Worker class 的方法内部调用 运行Worker(this)public无效运行(){ 运行工人(这个); }
runWorker()
执行这样的实际任务:void runWorker(Worker w) { try { w.lock(); w.firstTask.run() } finally { w.unlock(); } }
AQS 仅用于运行Worker() 方法的锁定和解锁。 我们不能在这里使用 ReentrantLock 并保持 Worker class 简单吗?
另外 class 提供有关此的文档,但我无法理解:
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.
请帮忙
您的问题的答案在您发布的 javadoc 的引述中:
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.
这是因为 可能正在等待任务的线程未被锁定 ,即 tryLock
returns true
。如果在这里使用 ReentrantLock
,在这种情况下会发生什么情况:那么可能会发生以下一系列操作:
setCorePoolSize
->interruptIdleWorkers
->tryLock()
(此处成功!)-> Thread.interrupt
(该工人的线程)
这会导致 worker 自身中断。