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

use*_*256 4 java multithreading notify java-threads

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

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

Nat*_*hes 7

这听起来像你看到的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消息只是暗示它在代码中发现了难闻的气味,因此您可以调查并查看问题的重要性.