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