バリアポイントをシミュレートするこのクラスを書いています。スレッドがこのバリア ポイントに到達すると、他のスレッドもこのポイントに到達するまで先に進むことができません。この時点で到着したスレッドの数を追跡するためにカウンターを使用しています。クラスは 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 行目で待機するため、ロックを維持することです。
このロックを回避する方法はありますか? この問題にどのようにアプローチすればよいですか?