使用Object.wait而不是Thread.sleep进行时间同步

时间:2016-08-22 16:25:41

标签: java android

我在可靠的来源(https://developer.android.com/guide/components/services.html#CreatingStartedService)中找到了这个例子

public class HelloIntentService extends IntentService {
  public HelloIntentService() {
      super("HelloIntentService");
  }
  @Override
  protected void onHandleIntent(Intent intent) {
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

问题是:为什么“睡觉”以这种方式实施,而不是这样:

endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
    try {
        Thread.sleep(endTime - System.currentTimeMillis());
    } catch (Exception e) {
    }
}

建议的方法更紧凑,并且没有任何线程可以在此对象上调用'notify'。无论如何,即使它存在,如果时间限制没有到期,程序将再次“进入睡眠状态”。那么编写更复杂和长代码以实现相同结果的隐藏原因是什么?

我已经看到了这个问题Difference between wait() and sleep(),但我的问题没有答案。 我也看过这个Using Object.wait(millisec) to simulate sleep,但我的问题更具体。

更新

无法相信developer.android.com为不同的语言(在我的情况下,英语和俄语)提供了不同的代码示例。也许它还没有更新..

看到这个屏幕截图: https://developer.android.com/guide/components/services.html#CreatingStartedService

2 个答案:

答案 0 :(得分:4)

Object.waitThread.sleep之间存在显着差异。 Object.wait会释放Thread拥有的所有监视器和锁,而Thread.sleep则不会。这本身就使得每种方法都有不同的用途。通常,Thread.sleep用于暂停执行,以便您无法控制的内容(如网络响应)完成某些操作,而Object.wait则用于通过等待和通知具体事件来同步您的应用程序(如消费者/生产者或发布者/订阅者模式)。

Thread.sleep docs

Object.wait docs

答案 1 :(得分:2)

因为他们做错了。

没有理由使用Object.wait实施5秒睡眠。 Object.wait用于同步,Thread.sleep用于休眠。

this上进行同步是另一个暗示,这一切都是错误的编程。 You should avoid it in general除非你有充分的理由,在这种情况下应该记录,但事实并非如此。

此外,当我关注您的链接时,我会在他们的页面中看到它:

 /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      try {
          Thread.sleep(5000);
      } catch (InterruptedException e) {
          // Restore interrupt status.
          Thread.currentThread().interrupt();
      }
  }
}

所以也许他们已经意识到自己的错误并纠正了它。

注意代码如何正确处理中断而不是像原始问题中的两段代码那样丢弃。