Java等效的.NET的ManualResetEvent和WaitHandle

我想知道Java是否提供了类似于.NET的ManualResetEvent和WaitHandle类,因为我想编写阻止给定超时的代码,除非触发事件。

WaitHandle和ManualResetEvent的.NET类为我提供了一个很好的,无障碍的接口,据我所知也是线程安全的,所以Java提供了什么?

您是否考虑过使用wait / notify (相当于Monitor.WaitMonitor.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()中添加一个额外的同步块似乎更明智,以便生成有保证的写屏障,并确保完整的primefaces性。 危险在于读取“开放”可能会在多处理器英特尔cpu上写下“开放”。 下面给出的改变的优点是:它可能不是最佳效率,但它确实具有保证没有错误的巨大优势,而且成本非常低。

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

感谢原版海报。