use*_*654 27

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 boolean waitOne(long milliseconds) throws InterruptedException {
    synchronized (monitor) {
      if (open) 
        return true;
      monitor.wait(milliseconds);
        return open;
    }
  }

  public void set() {//open start
    synchronized (monitor) {
      open = true;
      monitor.notifyAll();
    }
  }

  public void reset() {//close stop
    open = false;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @LimitedAtonement:在Java中,您必须处于同步块中才能等待对象.在等待期间,该对象的监视器锁定被释放,因此可以在另一个线程中获取.请参阅http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html (4认同)

Luc*_*ero 19

我所知道的最接近的是信号量.只需使用"许可"计数为1,而获取/发布将与您从中获知的几乎相同ManualResetEvent.

信号量初始化为1,并且使用的信号量最多只有一个许可证可用作互斥锁.这通常称为二进制信号量,因为它只有两种状态:一种是可用的,或者是零可用的.当以这种方式使用时,二进制信号量具有属性(与许多Lock实现不同),"锁"可以由除所有者之外的线程释放(因为信号量没有所有权的概念).这在某些特定的上下文中很有用,例如死锁恢复.

  • 是的,那是因为信号量没有所有权概念.它们是几乎同步的计数器,如果计数器为0,则线程等待. (3认同)

cra*_*fty 8

尝试CountDownLatch,计数为1.

CountDownLatch startSignal = new CountDownLatch(1);
Run Code Online (Sandbox Code Playgroud)

  • CountDownLatch的问题在于它不可重复使用.一旦闩锁达到0,就不能再使用了.它可以用新的锁存器实例替换,但这可以创建竞争条件,除非做得正确. (10认同)