Java中的并发阻塞标志

Java中的并发阻塞标志,java,concurrency,Java,Concurrency,我有时会编写如下代码: 方法1: 已同步(someMonitor){ newInfo=true; someMonitor.notifyAll(); } 方法2: 已同步(someMonitor){ 而(!newInfo){ someMonitor.wait(); } newInfo=false; } 我想API中有一个更高级别的并发对象来处理这个问题。它的工作原理应该是: 方法1: ensureReflagrased(); 方法2: blockUntilFlagRaisedThenLowe

我有时会编写如下代码:

方法1:

已同步(someMonitor){
newInfo=true;
someMonitor.notifyAll();
}
方法2:

已同步(someMonitor){
而(!newInfo){
someMonitor.wait();
}
newInfo=false;
}
我想API中有一个更高级别的并发对象来处理这个问题。它的工作原理应该是:

方法1:

ensureReflagrased();
方法2:

blockUntilFlagRaisedThenLowerFlag();
我可以使用容量为1的BlockingQueue调用非阻塞提供(DummeyElement)和阻塞take()。但这似乎是对该类的滥用


有更清洁的解决方案吗?

有几种方法可以做到这一点

最直接的替代方法是使用
Lock
Signal
进行切换,这与
synchronized/wait/notify
机制非常相似

但是对于一个简单的标志,最简单的方法可能是。使用它,您的示例代码可以如下所示:

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
但是
Semaphore
确实要求您正确规划逻辑,否则可能会导致死锁

不过,使用其他机制可以更好地解决生产者/消费者的情况,因为代码可能看起来很混乱,您需要跟踪谁在调用
acquire/release
以及何时调用。上述代码可以更好地通过以下方式实现:

交换器e=新交换器();
//生产者循环
e、 呼气(generateNewData());//忽视消费者的反应
//消费者环路
processData(例如交换(null));//获取数据,发送回虚拟

您可以使用或。java.util.concurrent中的很多东西都是用这个来构建的。这个信号量解决方案很有效。由于生产者可能会为使用者的单个循环多次循环,因此我将对其进行修改,使生产者只调用release(),然后消费者调用acquire(availablePermits())。这看起来仍然像是滥用API,但你的建议比我想到的解决方案要好。@JoshB它一点也没有滥用,信号量对于不同的用途非常通用。只需使用
drainPermits()
而不是
acquire(availablePermits())
。虽然我不明白你为什么不直接使用
阻塞队列
,但这似乎是一种基本的生产者/消费者情况。
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