在下面的代码片段中,我使用信号量来同步对某些资源的访问。

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


将获取/发布周期包含在一个try / final中可能是合理的。考虑到while循环的存在,我该怎么做?

最佳答案

根据必须发布的每个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();
    }
}

10-04 10:33