代码之家  ›  专栏  ›  技术社区  ›  Horcrux7

如何在没有阻塞的情况下调用Java中的NOTIFY()?

  •  1
  • Horcrux7  · 技术社区  · 14 年前

    是否有一个替代的Java代码不会阻塞?我只想ping一个可能的等待线程。我不想在监视器中已经存在的可能线程上进行任何更改。

    synchronized( monitor ) {
        monitor.notify();
    }
    
    5 回复  |  直到 14 年前
        1
  •  1
  •   Miklos Csuka    14 年前

    您可以使用java.util.concurrent.semaphore而不是monitor。二进制信号量可以与同步块具有相同的用途:

    private final Semaphore sema = new Semaphore(1, true); // binary: only 1 permit
    ....
    try {
        sema.acquire();   // blocks till permit is available
        try {
            // critical section code
            ....
        } finally {
            sema.release();   // release permit
        }
    } catch (InterruptedException ie) {
        ....
    

    您可以使用以下方法检查信号灯的状态:

    sema.availablePermits()  // 1 if no threads in critical section
    sema.getQueueLength()    // number of threads blocked waiting on acquire
    sema.getQueuedThreads()  // list of threads blocked waiting on acquire
    
        2
  •  2
  •   Robin    14 年前

    通知的要点是让等待监视器的其他线程知道他们可以尝试获取它。只有监视器的当前所有者才能发送通知,以指示已完成处理。

    为了拥有监视器,显然您阻塞了任何其他线程。这毕竟是监视器的目的。

        3
  •  1
  •   matsev    14 年前

    也许是一个 ReentrantLock 解决你的问题?例如

    class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...
    
       public void m() {
         lock.lock();  // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
     }

    此外,你还可以做

    lock.isLocked()

    lock.tryLock()
        4
  •  0
  •   Jeremy    14 年前
        5
  •  0
  •   David Soroko    14 年前

    不,你不能。如果您尝试类似的方法,您将得到一个“当前线程而不是所有者”。