[英]ManualResetEvent to IObservable<bool> (or WaitHandle to IObservable<Unit> )?
[英]Java Equivalent of .NET's ManualResetEvent and WaitHandle
我想知道Java是否提供了类似于.NET的ManualResetEvent和WaitHandle类,因为我想编写阻止给定超时的代码,除非事件被触发。
WaitHandle和ManualResetEvent的.NET类为我提供了一个很好的,无障碍的接口,据我所知也是线程安全的,所以Java提供了什么?
您是否考虑过使用wait
/ notify
(相当于Monitor.Wait
和Monitor.Pulse
)?
你需要进行一些检查,看看你是否真的需要等待(以避免竞争条件),但它应该有效。
否则,像CountDownLatch
这样的东西可能会做你想要的。
编辑:我刚刚注意到CountDownLatch
基本上是“单次使用” - 据我所知,你以后无法重置计数。 您可能需要Semaphore
。 像这样使用tryAcquire
等待超时:
if (semaphore.tryAquire(5, TimeUnit.SECONDS)) {
...
// Permit was granted before timeout
} else {
// We timed out while waiting
}
请注意,这与ManualResetEvent
不同,每次成功调用tryAcquire
都会减少许可数量 - 所以最终它们会再次耗尽。 您不能像使用ManualResetEvent
那样永久地“设置”它。 (那可以使用CountdownLatch
,但是你不能“重置”它:)
class ManualResetEvent {
private final Object monitor = new Object();
private volatile boolean open = false;
public ManualResetEvent(boolean open) {
this.open = open;
}
public void waitOne() throws InterruptedException {
synchronized (monitor) {
while (open==false) {
monitor.wait();
}
}
}
public void set() {//open start
synchronized (monitor) {
open = true;
monitor.notifyAll();
}
}
public void reset() {//close stop
open = false;
}
}
来自: http : //www.experts-exchange.com/Programming/Languages/Java/Q_22076798.html
嗨,您可以使用java.util.concurrent.Semaphore类实现同步(使用0 permit)。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html
下面的示例显示了如何解决第一个同步问题,另一个将类似:
import java.util.concurrent.Semaphore;
class ScalesCommunication {
private static Semaphore sem = new Semaphore(0);
// called by thread 1
void readLoop() {
//...
//after connection established, release semaphore (value incremented by 1)
sem.release();
}
// called by thread 2
String sendCommand(String command) {
sem.acquire(); // thread waits here if sem value == 0
// at this point connection is established
//...
}
}
理论上,上面给出的ManualResetEvent类在Java 5上是正确的(但不是更早)。 鉴于volatile的不正确(或不充分)实现的悠久历史,我在reset()中添加一个额外的同步块似乎更明智,以便生成有保证的写屏障,并确保完整的原子性。 危险在于读取“开放”可能会在多处理器Intel cpus上写入“open”。 下面给出的改变的优点是:它可能不是最佳效率,但它确实具有保证没有错误的巨大优势,而且成本非常低。
class ManualResetEvent {
private final Object monitor = new Object();
private volatile boolean open = false;
public ManualResetEvent(boolean open) {
this.open = open; }
public void waitOne() throws InterruptedException {
synchronized (monitor) {
while (open==false) {
monitor.wait();
}
}
}
public void set() {//open start
synchronized (monitor) {
open = true;
monitor.notifyAll();
}
}
public void reset() {//close stop
synchronized(monitor) {
open = false;
}
}
}
感谢原始海报。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.