2012-07-18 93 views
1

有一个主线程有一个while循环,在此期间,当他检查一些条件时,如果满足所有条件,他将启动另一个线程进入wait()状态。等待并通知协调

并行运行的其他线程在工作完成时通知主线程。

当“子线程”在之前通知主线程时,主线程进入等待状态=死锁存在问题。

避免它的最佳做法是什么?

回答

1

只要确保主线程不会等待已发生的事情。 (为什么有人会那样做呢?这没有任何意义。)

+1

+1:wait()的javadoc明确地解释了应始终有一个循环检查进入/退出等待状态的条件。 – 2012-07-18 05:49:50

0

使用旗语的通知。

就是这样,真的。信号量有一个计数,并可以记录通知,直到主线程开始等待。

0

简单的答案是使用Java 5中的并发包。CountDownLatch在这里看起来很合适。

如果您仅限于Java 5之前的环境,则必须创建一个使用相同算法的自定义实现。创建所有子线程后,主线程将调用signalReady。子线程在完成工作后会调用signalComplete。

一个简单的实现是将一个名为Latch的Object带有两个两个成员字段。

以下实施将适用于一位家长和一位子女。对于额外的孩子,每个孩子在完成时都可以给自己的闩锁发出信号。仍然会有这种情况会导致竞赛状况。在信号之间添加旋转锁定或可能是睡眠会降低竞争条件的可能性。 它不会消除它

class Latch{ 
    Object readyLock; 
    Object completeLock; 

    public void signalComplete(){ 
    synchronized(readyLock){ 
     readyLock.wait() 
    } 
    //spin lock as a precaution 
    synchronized(completeLock){ 
     completeLock.notify() 
    } 
    } 

    public void signalReady(){ 
    synchronized(readyLock){ 
     readyLock.notify() 
    } 
    synchronized(completeLock){ 
     completeLock.wait() 
    } 
    } 
} 

希望这有助于!

+0

这段代码被破坏严重,并造成OP询问的问题!即使没有什么需要等待,signalReady函数也会等待。 'signalComplete'函数完成同样的事情。 – 2012-07-18 07:18:19

0

这是一个非常普遍的做法几乎总是wait()方法在while循环,其“迭代条件”是检查是否已经发生特定事件时,发生其中的其他线程会被称为notify()方法。

例如:

while(!event_occurrence) { 
    ... 
    wait(); 
    ... 
} 

其中event_occurrence是其另一个线程会叫notify()法事件。

+0

我不认为这将有助于:如果有2个子线程。第一个子线程完成=> event_occurrence = true,主线程进入while循环。此时(执行wait()之前)子线程2完成。那么主线程再次执行wait()=>死锁 – markiz 2012-07-18 07:32:12

+0

@markiz:子线程2无法完成,除非此线程处于“等待”状态,因为此线程持有锁。 (它调用'wait'来释放锁以及等待事件。) – 2012-07-18 08:31:50

+0

@David Schwartz,锁定主线程。子线程唤醒主线程。主线程产生子线程并等待它们中的任何一个完成。然后他做了一些逻辑并再次入睡。 – markiz 2012-07-18 09:52:44