尽管使用了synchronized关键字,线程仍会陷入死锁

时间:2011-06-07 01:57:33

标签: java multithreading synchronization deadlock

我尝试在Java中创建一个事件调度程序,它将事件作为线程分派。所以所有EventListener类基本上都是Runnable类实现的。就像传统事件的触发一样,事件调度程序类中的方法循环遍历EventListeners列表然后调用它们的处理程序方法,除了这次,我通过将侦听器放入新的Thread(handlerObject)来调用这些处理程序作为线程。开始()。实际处理是在EventListener中的run()方法中完成的。

所以它看起来像:

for(EventListener listener : listenerList) {
   if(listener instanceof Runnable)
      new Thread(listener).start();
}

因此,在侦听器中处理事件的所有指令都放在run()方法中,该方法将在thread.start()时执行。

但问题是线程经常陷入其中一个线程卡在某处并且无法继续运行的情况。有时,一些线程也可能卡住,而有些线程设法运行监听器中run()方法中的所有指令。我抬起头来,听起来像是一个死锁。

我试图将“synchronized”修饰符放到我的所有方法中,但它仍然存在这个问题。我认为synchronized关键字只是将尝试运行类似方法的任何线程排队,直到运行该方法的当前线程完成为止。但这仍然没有解决问题。为什么不同步解决问题,特别是当我已经在我的所有方法上都有它并且应该排队任何可能导致死锁的并发访问?我没有使用任何wait()或notify()方法。只是一个简单的事件调度程序,它尝试将其事件侦听器作为线程运行。

我对线程很新,但发现调试它很困难,因为我不知道哪里出了问题。

感谢您的帮助。

4 个答案:

答案 0 :(得分:4)

死锁就是这样的:

  

需要铁来制作工具,请问B   铁
  B需要工具来制铁,   问一个工具

两者都不会完成。仅仅因为你已经将同步的关键词放在它们周围并不能保证你会遇到逻辑上的不可能性。你必须判断什么时候能够向前发展,何时不能发展。

答案 1 :(得分:1)

永远不要只为所有方法添加synchronized,这不会解决任何问题 - 您将有效地使您的程序成为单线程。

如果您认为自己有死锁,可以take a thread dumpanalyze the output来了解每个线程正在执行的内容,锁定(如果有)的内容,他们等待的锁等等

不幸的是,如果没有特定代码或理解应用程序中正在进行的实际同步,可以给出的唯一建议是这样的。

答案 2 :(得分:0)

我不知道你的'deadlock 是什么意思,尽管 synchronized keyword'。 `synchronized'关键字不能防止死锁。如果你有两个线程以不同的顺序获取锁,它可能会导致它们。解决方案:不要。

答案 3 :(得分:0)

你真正的问题是你不太了解并发性,无法理解你的程序无法正常工作的原因,更不用说如何解决这个问题。 (FWIW - 在所有方法中添加synchronized只会让问题变得更糟。)

我认为你最好的计划是抽出时间来阅读Java中的并发性。以下是一些很好的参考资料:


@wheaties有一个关于死锁是什么的微观解释,@ matt_b提供了有关如何诊断死锁的有用建议。但是,除非您知道设计和编写多线程代码的正确方法,否则这些方法无济于事。