2011-06-07 29 views
1

我试图在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关键字只是简单地排队尝试运行类似方法的任何线程,直到运行该方法的当前线程完成。但这并不能解决问题。为什么不同步解决问题,尤其是当我已经在我的所有方法上都有它时,它应该排队任何可能导致死锁的并发访问?我没有使用任何wait()或notify()方法。只是一个简单的事件调度程序,试图将其事件监听程序作为线程运行。

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

感谢您的任何帮助。

+4

FWIW,线程一般不会进入死锁**,除了**使用同步时。同步可以防止竞争条件,但会引入死锁的可能性。 – 2011-06-07 02:01:03

+0

真的很难回答你对你提供的信息的问题(你提供的循环看起来很好)。人们可能不得不看你的run()的实现来查看问题。你所遇到的可能不一定是死锁,它可能也是你的线程被一些非常长的I/O操作等阻塞。发布更多的代码给我们看,所以我们可以帮助你更好:)哦和任何体面的JAVA IDE应该可以让你暂停一个线程。试试Google“调试多线程java程序” – Alvin 2011-06-07 02:32:48

回答

4

死锁是沿此线的东西:

A需要铁来制造工具,要求B中 铁
B需要的工具,使铁, 要求一种工具

也不会完成。仅仅因为你把同步关键词放在他们身边并不能保证你会陷入逻辑不可能的境地。你必须判断一件事什么时候能够前进,什么时候不能。

1

不要只是将​​添加到所有方法,这不会解决任何问题 - 您将有效地使您的程序单线程。

当你认为你有一个僵局,您可以take a thread dumpanalyze the output了解了每个线程执行,哪些锁(如果有的话),他们都拿着,他们正在等待锁等

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

0

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

0

你真正的问题是,你不明白并发性足够理解你的程序不工作的原因,更不用说如何解决这个问题了。 (FWIW--将​​添加到您的所有方法只会使问题变得更糟)。

我认为您最好的计划是花时间阅读Java中的并发性。这里有几个很好的参考文献:


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