Java:在此示例中防止死锁

时间:2013-02-14 03:20:14

标签: java multithreading concurrency synchronization

尝试在Java中运用我对并发性的理解,这就是问题所在: 可以有多个线程运行方法A,只有一个线程运行方法B(假设当A()运行了10次。所以在第10次,该线程将运行方法B.当发生这种情况时,它必须阻止线程在运行B的其余部分之前,运行A并允许已经运行的线程完成。另外,A中的线程不应该等待自己。

编辑:首先在A上启动所有线程,有一个外部方法检查何时运行B.

到目前为止,我的尝试看起来像这样:

volatile Boolean lock = false; //false = threads in method A allowed to run, thread in method B otherwise
volatile Integer countOfA = 0;

void A(){
    boolean continue = false;
    synchronized(lock){
    if(lock == true){ //there is a thread in B, block threads in A
        lock.wait();

        increaseCountOfA();
        //do work
        decreaseCountOfA();

        if(countOfA == 0){ //this was the last thread that ran with lock
            lock = true;
            lock.notify(); //only the thread in B should be waiting on this
        }
      }else{
        continue = true;
      }
    }

    if(continue){
        increaseCountOfA();
        //do work;
        decreaseCountOfA();
    }
}

void B(){
  synchronized(lock){
    if(lock == false){
        lock.wait();
        if(countOfA > 0){
            countOfA.wait();
        }
        //do work;
        lock = false;
        lock.notifyAll();
    }
  }
}

void increaseCountOfA(){
  synchronized(countOfA){
    countOfA++;
  }
}

void decreaseCountOfA(){
  synchronized(countOfA){
    countOfA--;
  }
}

当它运行时,它会挂起。我怀疑死锁也不知道这个问题需要多少级别的同步。这可以只用一个级别来完成吗?

1 个答案:

答案 0 :(得分:0)

执行synchronized(lock)时,您正在同步lock引用的对象,而不是变量。您可能想要一个独立的锁定对象,其值不会发生变化。或者,您可以考虑使用更高级别的并发类,如Semaphore

在这种情况下,您有一个线程等待Boolean.TRUE,另一个线程在Boolean.FALSE上发布通知。