2

次のコード フラグメントでは、セマフォを使用して特定のリソースへのアクセスを同期しています。

public void m () {
    permit.acquire ();
    while (!canFoo ()) {
        permit.release ();
        reticulateSpines ();
        permit.acquire ();
    }
    doFoo ();
    permit.release ();
}

取得/解放サイクルを try/finally で囲むのが合理的かもしれません。while ループが存在する場合、どうすればこれを行うことができますか?

4

1 に答える 1

2

acquire すべてを解放しなければならないという原則について、私は次のことを提案します。

private final Semaphore permit = new Semaphore(8, true);
private final Random random = new Random();

private boolean canFoo() {
    return random.nextBoolean();
}

private void doFoo() {
    System.out.println("Foo done!");
}

private void reticulateSpines() {
    System.out.println("Spines reticulated!");
}

public void m() throws InterruptedException {
    permit.acquire();
    try {
        while (!canFoo()) {
            permit.release();
            try {
                reticulateSpines ();
            } finally {
                permit.acquire();
            }
        }
        doFoo();
    } finally {
        permit.release();
    }
}

ただし、意図したとおりにセマフォを使用しているかどうかはわかりません。ReentrantLockスピンロックループを排除するようなものを探しているように見えます。

ReadWriteLock fooLock = new ReentrantReadWriteLock();
Lock fooReadLock = fooLock.readLock();
Lock fooWriteLock = fooLock.writeLock();

public void n() throws InterruptedException {
    fooWriteLock.lock();
    try {
        doFoo();
    } finally {
        fooWriteLock.unlock();
    }
}

またはおそらく

public void o() throws InterruptedException {
    while (!fooWriteLock.tryLock()) {
        reticulateSpines();
    }
    try {
        doFoo();
    } finally {
        fooWriteLock.unlock();
    }
}
于 2014-05-15T22:35:26.303 に答える