我有Java中的旧代码,它会死锁...我从来没有使用netbeans作为开发工具...但是,我需要修复代码。如何使用NetBeans删除Java代码中的死锁
我在调试模式下运行应用程序,点击检查死锁,netBeans带来了一个屏幕。四个线程中的两个线程处于红色状态......请参阅下面的屏幕转储。
我新的多线程,并在该代码的顶部是不是我的......
什么是最有可能造成问题的原因?
我有Java中的旧代码,它会死锁...我从来没有使用netbeans作为开发工具...但是,我需要修复代码。如何使用NetBeans删除Java代码中的死锁
我在调试模式下运行应用程序,点击检查死锁,netBeans带来了一个屏幕。四个线程中的两个线程处于红色状态......请参阅下面的屏幕转储。
我新的多线程,并在该代码的顶部是不是我的......
什么是最有可能造成问题的原因?
至于我可以告诉这个问题很可能与中(或者更具体的顺序)的多个线程获取和释放锁的方式。 在上述例子中的两个线程需要访问两个锁(或监视器):
从堆跟踪当前处于死锁状态的两个线程,我们可以看到线程'ExecutionManager'获得了ExecutionManager监视器,但正在等待'ESMarketMaker'监视器正在等待获取(同时仍持有'ExecutionManager'监视器)。
另一方面,'StrategyManager'线程已经获得'ESMarketMaker'监视器,但正在等待'ExecutionManager'监视器的获取(同时仍持有'ESMarketMaker'监视器)。
这是一个死锁的类示例,以及获取锁的顺序会导致死锁的很多方法。
有解决这些类型的问题很多:
但有一点需要注意的是,有时候在决定使用协议时,需要更多地显式控制您的锁,而不是使用Java中的常规同步。在这些情况下,显式ReentrantLock实例的使用可以是一个好处,因为它们允许您执行诸如检查锁是否已解锁或当前已锁定等操作,并执行上述非阻塞try-lock。
我希望这可以帮助,我很抱歉,我不能更具体,但我需要看到源代码。:-)
(哦,ps,人们可能会选择的第三件事,如果死锁是所有成本都必须避免的事情,那就是研究建模工具,在程序状态上建模一个状态机和锁,它们可以与分析工具一起使用,分析工具可以检查这种模型中可能存在的死锁并给出示例,如果发现任何这样的情况)。
+1 ...但我不同意释放锁和重新获取它们的部分。如果两个代理做同样的事情,那么他们可能会遇到一个活锁。基本上,两个代理不断获得第一个锁,未能获得第二个锁,释放第一个锁,并连续重复该过程。 – 2010-10-19 23:21:04
这当然是对的,这样的条件在理论上是可行的,因此应该谨慎使用解决方案,因为它不是防弹的。尽管如此,我认为这样的调度(在现实生活中)不大可能不说不存在,因为它需要无限期地一致地调度“错误”的交错。有人可能称之为“解决方案”乐观,因为它依赖于调度器的伪随机行为来确保(在无限期的时间内)在某个点尝试“正确”交织。 – micdah 2010-10-19 23:35:37
也许一个更好的解决方案,假设人们事先知道准确执行操作所需的锁,就是试图在每次重试时以伪随机顺序获取这些锁,直到获得所有锁,这种随机性与非阻塞获取相结合肯定会(给定无限期)确保线程在某个时刻可以获得所有需要的锁。 – micdah 2010-10-19 23:39:17