Pregunta

In the following code fragment I'm using a semaphore to synchronize access to certain resources.

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

It might be reasonable to enclose the acquire/release cycles in a try/finally. How can I do this, given the presence of the while loop?

¿Fue útil?

Solución

On the principle of every acquire must be released I would suggest:

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();
    }
}

However - I am not sure of you are using Semaphores as they are intended. It looks much more like you are looking for something like ReentrantLock which would eliminate spinlock loop.

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

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

or even perhaps

public void o() throws InterruptedException {
    while (!fooWriteLock.tryLock()) {
        reticulateSpines();
    }
    try {
        doFoo();
    } finally {
        fooWriteLock.unlock();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top