当前位置: 首页 > 知识库问答 >
问题:

为什么ThreadPoolExecutor$Worker扩展AbstractQueuedSynchronizer

欧阳山
2023-03-14

我知道一些关于AbstractQueuedSynchronizer的详细信息。它是一个用于创建依赖于状态的类或同步器的框架。但我不理解在ThreadPoolExecutor的Worker中扩展这个类的意义。

private final class Worker extends AbstractQueuedSynchronizer implements Runnable

由Worker类的签名可以推断出以下内容:

>

  • 提交新的可运行/可调用任务时,将创建一个新的工作对象。

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

    addWorker()方法将添加新的worker(或只是一个任务)并在其自身中调用worker。start()启动线程。

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

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

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

    runWorker()执行实际任务,如下所示:

    空runWorker(Worker w){try{w.lock();w.firstTask.run()}最后{w.unlock (); } }

    AQS仅用于runWorker()html" target="_blank">方法的这种锁定和解锁。我们不能在这里使用ReentantLock并保持Worker类简单吗?

    课程还提供了相关文档,但我无法理解:

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

    请帮忙


  • 共有1个答案

    邵昆琦
    2023-03-14

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

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

    这是因为可能正在等待任务的线程表示未被锁定,即为它们返回true。如果在这里使用ReentrantLock,在这种情况下会发生什么:那么可能会有以下操作序列:

    setCorePoolsize-

    这将导致工作进程自身中断。

     类似资料:
    • 扩展是可定制化浏览体验的小程序,它们使用户可以根据个人需要或者偏好定制 Chrome 的功能和行为。它们基于 Web 技术(例如 HTML,JavaScript 和 CSS)构建。 扩展必须满足狭义定义且易于理解的单一目的(译者注:功能简单易懂化)。一个扩展可以包括多个组件和一系列功能,只要所有的内容都有助于实现共同的目标。 用户交互界面应尽量小且有意图。他们的范围从简单的图标,如右侧显示的 Go

    • 问题内容: 创建数组时,无法更改其大小;它是固定的。好的,看起来不错,我们可以创建一个新的更大的数组并逐个复制值,这有点慢。它的技术背景是什么? 问题答案: 这个问题没有提到语言,因此我将选择基于“ C”的数组作为答案。 数组被分配为单个内存块。增长数组是有问题的,因为正确执行此操作的唯一方法是在最后增长它。为了增加大小N,在数组的末尾必须在下一个分配的地址之前至少有N个空闲字节。 要支持这种类型

    • 问题内容: 事实并非如此,这让我感到惊讶。 我认为,如果这样声明,那将是很有意义的: 毕竟,是的集合,不是吗? 那么,为什么没有这样一个很好的实现呢? 感谢Cletus提供的最权威的答案,但是我仍然想知道为什么,如果你已经可以查看(通过),那么它不仅扩展了该接口。 如果a 是a ,则元素是什么?唯一合理的答案是“键值对” 确实会很棒! 但这提供了非常有限的(且不是特别有用的)Map抽象。 但是,如

    • 问题内容: 我想知道为什么在Java语言中a 不能扩展。 我不是在谈论一个延伸的(这不能做,因为Java没有多重继承,而Š隐含延长),但一类的以只添加额外的方法,而不是额外的枚举值。 就像是: 要这样使用: 因此,有人可以对此限制提供理由(或将我指向正确的JLS部分)吗? 问题答案: 我认为 他们这样做 的答案来自以下问题: 在您的示例中,如何实例化MyClass?用户永远不会(通过)显式实例化枚

    • 问题内容: 为什么接口不扩展接口?不是键值对的集合吗? 问题答案: 集合假定一个值的元素。映射假定键/值对的条目。他们本来可以重新使用相同的通用接口,但是它们实现的某些方法不兼容,例如 您可以将Map建模为条目的集合,这就是这样做的。 有一些共同的方法。,,,但这些都不太可能有多少价值作为一个独立的接口。(可以再次使用)

    • 问题内容: 今天打开了LinkedHashSet源代码,发现了一些有趣的东西: 问题是:为什么当HashSet已经是Set时,为什么它们既需要“ extends HashSet”又需要“ implements Set”? 问题答案: 我问过乔什·布洛赫(Josh Bloch),他告诉我这是一个错误。很久以前,他曾经认为其中有一些价值,但是他自从“看到了光”。显然,JDK维护人员认为以后不应该撤消此