Josh B
Josh B

Reputation: 247

Concurrent Blocking Flag in Java

I sometimes write code like:

Method 1:

synchronized (someMonitor) {
    newInfo = true;
    someMonitor.notifyAll();
}

Method 2:

synchronized (someMonitor) {
    while (!newInfo) {
        someMonitor.wait();
    }
    newInfo = false;
}

I imagine there's a higher-level concurrency object in the API to handle this. It should work like:

Method 1:

ensureFlagRaised();

Method 2:

blockUntilFlagRaisedThenLowerFlag();

I could use a BlockingQueue with capacity 1 to call the non-blocking offer(dummyElement) and the blocking take().  But this seems like an abuse of that class.

Any cleaner solutions?

Upvotes: 2

Views: 369

Answers (1)

Kayaman
Kayaman

Reputation: 73528

There are several ways you can do this.

The most direct replacement would be to switch using Lock and Signal, which mimics closely the synchronized/wait/notify mechanism.

But for a simple flag, the easiest approach is probably a Semaphore. With it, your example code could look like the following:

Semaphore s = new Semaphore(0, true); // No permits to start with, acquire will block

// Producer loop
makeNewDataAvailable();
s.release();  // Raise "flag" to indicate new info
possiblyDoSomethingUseful();
s.acquire();  // A fair semaphore, so waiting threads get the permit

// Consumer loop
s.acquire();  // Blocks until "flag" raised, then acquires it
processNewData();
s.release();  // Pass the permit back to thread 1

But Semaphore does require you to plan your logic correctly, otherwise you could end up in a deadlock.

A producer/consumer situation is solved better with other mechanisms though, as you see the code can look confusing and you need to keep track of who's calling acquire/release and when. The above code could be better implemented with for example Exchanger:

Exchanger<String> e = new Exchanger<>();

// Producer loop
e.exhange(generateNewData());  // Ignore consumer's response

// Consumer loop
processData(e.exchange(null)); // Get data, send dummy back

Upvotes: 4

Related Questions