Reputation: 32680
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?
Upvotes: 2
Views: 2796
Reputation: 65821
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();
}
}
Upvotes: 2