繁体   English   中英

为什么不能在Thread实例中使用notifyAll()?

[英]Why can't notifyAll() be used in a Thread instance?

我正在使用一个源代码分析器,指出不应在Thread实例中调用notifyAll()。 我试图向管理层说明这一点,但我无法提出解释。 有人能帮我吗??

顺便说一句,这是继承的代码,所以我不负责设计决策!

这听起来像你看到的SONAR消息就是这个

方法永远不应该在线程实例squid上调用“wait(...)”,“notify()”和“notifyAll()”:S2236

声纳对此有详细解释:

在Thread实例上,方法wait(...),notify()和notifyAll()仅可用,因为Java中的所有类都扩展了Object,因此会自动继承这些方法。 但是有两个很好的理由不在Thread实例上调用这些方法:

这样做真的很令人困惑。 调用例如Thread上的wait(...)方法时真正期望的是什么? 是暂停执行Thread还是等待对象监视器的获取?

在内部,JVM依赖于这些方法来改变Thread的状态(BLOCKED,WAITING,...),因此调用它们将破坏JVM的行为。

同样, Java API中给出建议是:

建议应用程序不要在Thread实例上使用wait,notify或notifyAll。

内部线程管理是通过锁定线程对象来完成的。 如果您自己的应用程序代码锁定线程,则可能会出现意外或混乱的行为。 例如,当一个线程终止时,它会向等待它的每个线程发送一个通知。

在尝试评估问题的可能性时,我会查找线程可能会收到错误通知或错过通知的情况,因为它被用作应用程序代码的锁和内部JVM代码的锁。 (这看起来可能很乏味。)根据代码,我还会查找由于锁定线程而导致的可能的一致性问题,而不是锁定线程访问的数据结构,并评估锁定方案是否有意义。 如果代码是子类化线程我想要检查线程是否汇总以及如何。

大多数情况下,这条消息会让我想到,如果这段代码做了一件坏事,那还有什么可能做错了? SONAR消息只是暗示它在代码中发现了难闻的气味,因此您可以调查并查看问题的重要性。

你不应该对Thread进行子类化。 这样做会打开一系列相当清楚的问题。 使用wait / notifyAll不是一个很好的选择,因为并发库是在十多年前添加的,但在Thread上它特别糟糕,因为Thread类也使用wait / notify来达到自己的目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM