2016-07-03 10 views
2

バリアポイントをシミュレートするこのクラスを作成しています。スレッドがこのバリアポイントに到達すると、他のスレッドもこのポイントに到達するまで続行できません。私は、この時点で到着したスレッドの数を追跡するためにカウンタを使用しています。クラスはN + 1個のスレッドを期待しているが、N個のスレッドしか与えられていないと仮定する。この場合、プログラムは到着するスレッドがまだもう1つあると考えているため、すべてのスレッドを待機させます。待機中のスレッドをすべて解放する

バリアポイントに到達するスレッドがまだ残っているかどうかにかかわらず、すべての待機スレッドを解放できる方法を書いておきたいと思います。

すべてのスレッドを待つために私のプログラムは、

public volatile int count; 
public static boolean cycle = false; 

public static Lock lock = new ReentrantLock(); 
public static Condition cv = lock.newCondition(); 

public void barrier() throws InterruptedException { 
    boolean cycle; 
    System.out.println("lock"); 
    lock.lock(); 
    try { 
     cycle = this.cycle; 
     if (--this.count == 0) { 
      System.out.println("releasing all threads"); 
      this.cycle = !this.cycle; 
      cv.signalAll(); 
     } else { 
      while (cycle == this.cycle) { 
       System.out.println("waiting at barrier"); 
       cv.await(); // Line 20 
      } 
     } 
    } finally { 
     System.out.println("unlock"); 
     lock.unlock(); 
    } 
} 

私は単にsignalAll()メソッドを呼び出して、すべてのスレッドが無料になる方法を作成することができます考えていました。しかし、私が抱えている問題は、プログラムがさらにスレッドを待っている場合、行20で待機するためロックを維持するということです。

このロックを回避する方法はありますか?私はこの問題にどのようにアプローチすべきですか?

+0

'this.cycle = this.cycle。 cv.signalAll(); '? – immibis

+0

これが再利用可能な障壁である場合、freeAllコールの後に到着するスレッドで何が起こるべきかを決定しなければならず、freeAllはthis.countをリセットする必要があります。 – immibis

答えて

0

良いアイデア - 標準java.util.concurrentのプリミティブを使用 - 'リセット' の方法でCyclicBarrierをを!

/** 
* Resets the barrier to its initial state. If any parties are 
* currently waiting at the barrier, they will return with a 
* {@link BrokenBarrierException}. Note that resets <em>after</em> 
* a breakage has occurred for other reasons can be complicated to 
* carry out; threads need to re-synchronize in some other way, 
* and choose one to perform the reset. It may be preferable to 
* instead create a new barrier for subsequent use. 
*/ 
public void reset() 
関連する問題