线程间使用wait()和notify()协作可能造成潜在死锁

在并发编程中,有时候需要使任务彼此之间可以协作,这里举一个存在问题的例子,看上去执行正确,但实际有潜在的死锁。

 

当线程使用notify()/wait()或notifyAll()/wait()进行协作时,在wait()的一方可能会错失notify()/notifyAll()的信号,而一直处于wait()中造成死锁。


假设有T1和T2两个线程,T1是通知T2的线程,这两个线程使用下面的方式实现的:

T1:
synchronized(sharedMonitor) {
    someCondition=false
    sharedMonitor.notify();
}


T2:
while(someCondition) {
    //Point 1
    synchronized(sharedMonitor) {
        sharedMonitor.wait();
    }
}


是防止T2调用wait()的一个动作,当然前提是T2还没有调用wait()。假设T2对someCondition求值并发现其为true。


在Point 1,线程调度器可能切换到了T1,T1将执行其设置,设置someCondition=false,然后调用notify()。当T2得以继续执行时,对于T2来说时机已经太晚了,错过了T1的notify()信号,无法意识到someCondition条件已经改变了,还是盲目进入wait(),将无限的等待,产生死锁。

 

该问题根本原因是两个任务在someCondition条件上产生了竞争,我们需要使用互斥锁机制避免共享资源竞争的出现,T2正确的执行方式应该是:

T2:
synchronized(sharedMonitor) {
    while(someCondition) {
        sharedMonitor.wait();
    }
}


wait()/notify()、wait()/notifyAll()的正确使用方式,必须在同步控制块中使用。

 

原文转自:http://blog.sina.com.cn/s/blog_97eedec40101dlnu.html

你可能感兴趣的:(多线程)