如何理解 wait() 是从超时返回还是从 notify() 返回?

How to understand if wait() returned from timeout or from a notify()?

我有一个等待线程:

synchronized(sharedCounter) {
  while(sharedCounter > 0) {
    sharedCounter.wait(60000); //wait at most 1 minute
    /*if it wakens from the end of the timeout, it should break the loop
      or it could potentially restart the timeout*/
  }
}

还有一个可以通知的线程:

synchronized (sharedCounter) {
  if(sharedCounter == 0) 
    sharedCounter.notify(); 
}

如何区分通知和超时?

我可以这样做:

synchronized(sharedCounter) {
  while(sharedCounter > 0) {
    sharedCounter.wait(60000); 
    if(sharedCounter == -1) { //if it was a notify()
      //I could save the fact that it was a notify() here
      break;
    }
    //Otherwirse, assume it was a timeout, save the fact and break
    break;
  }
}

synchronized (sharedCounter) {
   if(sharedCounter == 0) {
     sharedCounter = -1; //to signal that it comes from a notify()
     sharedCounter.notify(); 
   }
}

问题是,虚假唤醒会破坏我的设计。

你会如何处理这个问题?

没有办法。您必须自己向多线程应用程序添加逻辑以区分这些情况。

使用更复杂的并发原语,一个 Condition. Acquire one from a Lock with Lock#newCondition(). You then have access to a Condition#await(long, TimeUnit) 方法,其中 returns 一个 boolean 的值为

false if the waiting time detectably elapsed before return from the method, else true

例如,

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// ... (share the object across threads)
if (condition.await(10, TimeUnit.SECONDS)) {
    // signaled (equivalent of notify)
} else {
    // time elapsed
}
// ... (in other thread)
condition.signal();

除非在 Condition 实施文档中另有规定,否则虚假唤醒将在内部处理。你不用担心他们。

这是一道假题。例如,如果等待超时返回,但在 sharedCounter 设置为 -1 之后立即 - 您是否仍想对超时或 -1 做出反应?