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 行目で待機するため、ロックを維持することです。

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

4

1 に答える 1

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()
于 2016-07-04T18:14:51.027 に答える