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

Kam*_*ami 1 java multithreading synchronization

我有一个等待线程:

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*/
  }
}
Run Code Online (Sandbox Code Playgroud)

一个可以通知的线程:

synchronized (sharedCounter) {
  if(sharedCounter == 0) 
    sharedCounter.notify(); 
}
Run Code Online (Sandbox Code Playgroud)

如何区分通知和超时?

我可以这样做:

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(); 
   }
}
Run Code Online (Sandbox Code Playgroud)

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

你会如何处理这个问题?

Sot*_*lis 6

使用更复杂的并发原语,a Condition.获得一个从LockLock#newCondition().然后,您可以访问一个Condition#await(long, TimeUnit)返回boolean值为的方法

false 如果在从方法返回之前可检测到的等待时间已经过去,否则 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();
Run Code Online (Sandbox Code Playgroud)

除非在Condition实现文档中另有规定,否则虚假唤醒将在内部处理.你不必担心它们.