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

时间:2015-06-21 15:00:45

标签: 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*/
  }
}

一个可以通知的线程:

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

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

你会如何处理这个问题?

3 个答案:

答案 0 :(得分:6)

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

OBJ
  

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(); 实施文档中另有规定,否则虚假唤醒将在内部处理。你不必担心它们。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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