简体   繁体   中英

Java Equivalent of .NET's ManualResetEvent and WaitHandle

I would like to know if Java provides an equivalent of .NET's classes of ManualResetEvent and WaitHandle, as I would like to write code that blocks for a given timeout unless an event is triggered.

The .NET classes of WaitHandle and ManualResetEvent provide a nice, hassle-free interface for that which is also thread-safe as far as I know, so what does Java has to offer?

Have you considered using wait / notify (the equivalent of Monitor.Wait and Monitor.Pulse ) instead?

You'll want a little bit of checking to see whether you actually need to wait (to avoid race conditions) but it should work.

Otherwise, something like CountDownLatch may well do what you want.

EDIT: I've only just noticed that CountDownLatch is basically "single use" - you can't reset the count later, as far as I can see. You may want Semaphore instead. Use tryAcquire like this to wait with a timeout:

if (semaphore.tryAquire(5, TimeUnit.SECONDS)) {
   ...
   // Permit was granted before timeout
} else {
   // We timed out while waiting
}

Note that this is unlike ManualResetEvent in that each successful call to tryAcquire will reduce the number of permits - so eventually they'll run out again. You can't make it permanently "set" like you could with ManualResetEvent . (That would work with CountdownLatch , but then you couldn't "reset" it :)

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

From: http://www.experts-exchange.com/Programming/Languages/Java/Q_22076798.html

Hi, you can achieve synchronization using the java.util.concurrent.Semaphore class (use 0 permit).

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html

Example below shows you how to solve the first sync problem, the other will be similar:

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
       //...
   }
}

In theory, the ManualResetEvent class as given above is correct on Java 5 (but not earlier). Given the long history of incorrect (or inadequate) implementations of volatile, it seems wiser to me to add an additional synchronized block in reset() in order to generate a guaranteed write barrier, and ensure complete atomicity. The danger is that a read of "open" may pass a write of "open" on multi-processor Intel cpus. The advantage of the change given below: it may not be optimally efficient, but it does have the great advantage of being guaranteed to be not wrong, at very little additional cost.

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

Thanks to the original poster.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM