首页 文章

为什么ThreadPoolExecutor $ Worker扩展了AbstractQueuedSynchronizer

提问于
浏览
1

我知道有关AbstractQueuedSynchronizer的一些细节 . 它是一个用于创建状态依赖类或同步器的框架 . 但是我没有在ThreadPoolExecutor的Worker中扩展这个类 .

private final class Worker extends AbstractQueuedSynchronizer implements Runnable

正如 Worker 类的签名所见,可以推断出以下事项:

  • 提交新的Runnable / Callable任务时,将创建一个新的Worker对象 .

  • Worker的新对象可以被视为新线程 .

  • addWorker() 方法将添加新工作者(或简称为任务)并自行调用 worker.start() 以启动该线程 .

  • Worker类是非静态嵌套类,因此它可以访问ThreadPoolExecutor的所有变量

  • run() Worker类的方法在内部调用runWorker(this)

public void run(){runWorker(this); }

  • runWorker() 执行如下的实际任务:

void runWorker(Worker w) { try { w.lock(); w.firstTask.run() } finally { w.unlock(); } }

AQS仅用于此锁定和解锁runWorker()方法 . 我们不能在这里使用ReentrantLock并保持Worker类简单吗?

类也提供了相关的文档,但我无法理解:

此类机会性地扩展AbstractQueuedSynchronizer以简化获取和释放围绕每个任务执行的锁定 . 这可以防止意图唤醒等待任务的工作线程而不是中断正在运行的任务的中断 . 我们实现了一个简单的非重入互斥锁而不是使用ReentrantLock,因为我们不希望工作任务在调用setCorePoolSize等池控制方法时能够重新获取锁 .

请帮忙

1 回答

  • 2

    您的问题的答案在javadoc的引用中,您发布的:

    我们实现了一个简单的非重入互斥锁而不是使用ReentrantLock,因为我们不希望工作任务在调用setCorePoolSize等池控制方法时能够重新获取锁 .

    那是因为 threads that might be waiting for tasks are indicated by not being locked ,即 tryLock 为他们返回 true . 在这种情况下会发生什么情况,如果 ReentrantLock 将在这里使用:那么它可能会遵循一系列动作:

    setCorePoolSize - > interruptIdleWorkers - > tryLock() (这里成功!) - > Thread.interrupt (这个 Worker 的线程)

    这将导致 Worker 自己中断 .

相关问题