Jason S Jason S - 11 months ago 69
Java Question

java concurrency: lightweight nonblocking semaphore?

I have a situation where I have a callback that I want to execute once. For the sake of argument let's say it looks like this:

final X once = new X(1);
Runnable r = new Runnable() {
@Override public void run() {
if (once.use())

where X is some concurrent object with the following behavior:

  • constructor: X(int N) -- allocates N use permits

  • boolean use()
    : If there is at least 1 use permit, consume one of them and return true. Otherwise return false. This operation is atomic with respect to multiple threads.

I know I can use java.util.concurrent.Semaphore for this, but I don't need the blocking/waiting aspect of it, and I want this to be a one-time use thing.

AtomicInteger doesn't look sufficient unless I do something like

class NTimeUse {
final private AtomicInteger count;
public NTimeUse(int N) { this.count = new AtomicInteger(N); }
public boolean use() {
while (true)
int n = this.count.get();
if (n == 0)
return false;
if (this.count.compareAndSet(n, n-1))
return true;

and I feel queasy about the while loop.

CountDownLatch won't work, because the countDown() method has no return value and can't be executed atomically w/r/t getCount().

Should I just use Semaphore or is there a more appropriate class?


In the case of single permit you can use AtomicBoolean:

final AtomicBoolean once = new AtomicBoolean(true);
Runnable r = new Runnable() {
    @Override public void run() {
        if (once.getAndSet(false))

If you need many permits, use your solution with compareAndSet(). Don't worry about the loop, getAndIncrement() works the same way under the cover.