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 回答