适用于Java Reentrant锁的锁定/解锁使用

时间:2013-02-06 18:20:27

标签: java synchronization

我有一个名为“H2O问题”的作业,我应该实现一个名为H2OBarrier的类,它有3种方法。

  • HReady,一种在氢原子(线程)准备就绪时调用的方法
  • OReady,一种在氧原子(线程)准备就绪时调用的方法
  • makeWater,一种在准备2个氢原子和一个氧原子时称为的方法

我应该使用Java Reentrant锁和条件来执行此操作。

到目前为止,这是我的代码,我想知道我是否正确使用锁定和解锁。

public class H2OBarrier {

int hCount;
int oCount;

Lock lock = new ReentrantLock();
Condition hWait = lock.newCondition();
Condition oWait = lock.newCondition();

public void HReady() {
    lock.lock();
    hCount++;

    try {
        hWait.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

public void OReady(){
    lock.lock();
    oCount++;

    try {
        while(hCount<2 && oCount<1){
            oWait.await();
        }   
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        makeWater();
    }


}

public void makeWater(){
    hCount--;
    hWait.signal();
    lock.unlock();

    hCount--;
    hWait.signal();
    lock.unlock();

    oCount--;
    oWait.signal();
    lock.unlock();

}

} 

我应该在makeWater方法以外的任何地方调用unlock()吗?程序的整个流程对我来说似乎很合乎逻辑,我只是​​想确保我所做的事情看起来总体上是正确的。

1 个答案:

答案 0 :(得分:2)

您的代码正在产生死锁。想象一下,5个原子首先通过,5个进入由await()生成的队列。现在无论2 h原子是否通过,所有h原子都会因为你的代码而自动等待。