java - 如何使用 NetBeans 消除 Java 代码中的死锁

标签 java multithreading deadlock

我在 Java 中有旧代码会死锁...我从未将 netbeans 用作开发工具...但是,我需要修复代码。

我在 Debug模式下运行应用程序,单击检查死锁,然后 netBeans 显示了一个屏幕。四分之二的线程是红色的...请参阅下面的屏幕转储。

我是多线程的新手,最重要的是代码不是我的...

最有可能导致问题的原因是什么?

alt text

最佳答案

据我所知,问题很可能与多线程获取和释放锁的方式(或更具体地说是顺序)有关。 在上面的例子中,两个线程需要访问两个锁(或监视器):

  • nano.toolbox.strategies.ESMarketMaker
  • nano.toolbox.strategies.ExecutionManager

从当前处于死锁状态的两个线程的堆栈跟踪中,我们可以看到线程“ExecutionManager”已获取 ExecutionManager 监视器,但正在等待“ESMarketMaker”监视器的获取(同时仍持有“ExecutionManager”监视器)。

另一方面,“StrategyManager”线程已获取“ESMarketMaker”监视器,但正在等待“ExecutionManager”监视器的获取(同时仍持有“ESMarketMaker”监视器)。

这是死锁的类示例,以及获取锁的顺序可能导致死锁的多种方式。

有很多方法可以解决这类问题:

  • 如果可能,所有需要一组锁来操作的线程必须以相同的顺序获取共享锁(倒序就是上述死锁中的问题)。但这并不总是可能的,因为多个线程在不同条件下可能只有半重叠的锁使用,因此可能很难或不可能设计一个确保统一排序的获取协议(protocol)。
  • 您也可以改用 tryLock(),这是一种非阻塞获取,它会返回一个标志以指示成功或失败,并让您可以选择在重试之前执行其他操作。在这种情况下我会推荐的一件事是,如果获取失败,它是放弃所有当前拥有的锁并再次从头开始尝试(从而为任何被当前线程持有的任何或所有锁阻塞的人让路,以完成他们的工作,也许在重试时释放该线程所需的锁)。

但要注意的一件事是,有时在决定要使用的协议(protocol)时,您需要对锁进行更明确的控制,而不是 Java 中的正常同步。在这些情况下,显式 ReentrantLock 实例的使用可能是一个好处,因为它们允许您执行诸如检查锁是否已解锁或当前已锁定之类的操作,并执行非阻塞尝试锁,如上所述。

我希望这会有所帮助,很抱歉我不能说得更具体,但我需要查看源代码。 :-)

(哦,附言,如果必须不惜一切代价避免死锁,那么人们可能会选择的第三件事是研究建模工具,根据程序和锁的状态对状态机进行建模,这可以与分析工具一起使用,分析工具可以检查此类模型中可能存在的死锁,并在发现此类死锁时提供示例)。

关于java - 如何使用 NetBeans 消除 Java 代码中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3973108/

相关文章:

mysql - 如何导致MySQL死锁

objective-c - 这个递归同步调用怎么不死锁呢?

java - ElasticSearch Java API : Update Existing Document

java - 如何使用 Java 登录网站并保持登录状态?

java - 如何根据深层嵌套对象内的字段对 Realm 进行排序?

java - 高性能且线程安全的初始化 block

c++ - 在卸载 DLL 期间删除静态对象时退出线程会导致死锁?

java - 我想要获得一周的值(value)

Java 线程问题,处理程序消息数据被下一条消息覆盖

java - Hibernate:从不同线程插入具有唯一约束的对象