0

I have found this example in reliable source (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) {
              }
          }
      }
  }
}

The question is: Why "sleeping" was implemented this way, and not like this:

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

The suggested approach is more compact, and there is no any thread that can call 'notify' on this object. Anyway, even if there it was, the program will "go to sleep" again, if time limit was not expired. So what is hidden reason to write more complex and long code to achieve the same result?

I've seen this question Difference between wait() and sleep() , but it has no answer for my question. I also have seen this Using Object.wait(millisec) to simulate sleep , but my question is more specific.

UPDATE

Can't believe that developer.android.com provides different code samples for different languages (in my case, for English and Russian). Maybe it just have not been updated yet..

See this screen-shot: https://developer.android.com/guide/components/services.html#CreatingStartedService

Community
  • 1
  • 1
B-GangsteR
  • 2,534
  • 22
  • 34
  • 1
    "I have found this example in reliable source" -- none of that code appears on the Web page that you cite. This is good, as both are anti-patterns with respect to `IntentService`. – CommonsWare Aug 22 '16 at 16:38
  • @CommonsWare Thanks for comment, I have updated my question. They provide different code samples for different languages. About fact of "sleeping" in Service - it's not important in this case, it's just sample of using IntentService, instead of writing code sample that will do some comprehended job. – B-GangsteR Aug 22 '16 at 20:41
  • 1
    "They provide different code samples for different languages" -- ick. I filed [an issue](https://code.google.com/p/android/issues/detail?id=220632) on this, but documentation issues are ignored most of the time, so I have little hope. I'll have to keep this in mind for the future. My apologies for doubting you! – CommonsWare Aug 22 '16 at 20:57
  • @CommonsWare That's all right! – B-GangsteR Aug 22 '16 at 21:36

2 Answers2

4

There is a significant difference between Object.wait and Thread.sleep. Object.wait releases any monitors and locks owned by the Thread, while Thread.sleep does not. That in itself makes each of those methods have different purposes. Normally, Thread.sleep is used to pause execution so that something out of your control (like a network response) finishes doing something, while Object.wait is used to synchronize your application by waiting and notifying on concrete events (like a consumer/producer or publisher/subscriber pattern).

Thread.sleep docs

Object.wait docs

Marcel Valdez Orozco
  • 2,985
  • 1
  • 25
  • 24
2

Because they did it wrong.

There is no reason to implement that 5 second sleeping using Object.wait. Object.wait is used for synchronization and Thread.sleep for sleeping.

Synchronizing on this is another hint that it all is bad programming. You should avoid it in general unless you have a really good reason for it and in such case it should be documented, which is not the case.

Furthermore when I follow your link I see it this way in their page :

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

So maybe they have realized of their mistake and corrected it.

Take notice of how in that code interrupts are properly handled rather than discarded as in the two pieces of code in the original question.

Community
  • 1
  • 1
Anonymous Coward
  • 3,140
  • 22
  • 39
  • You are right, thanks for explanation and noticing about interruption handling. It also can be found here: http://stackoverflow.com/questions/4906799/why-invoke-thread-currentthread-interrupt-when-catch-any-interruptexception – B-GangsteR Aug 27 '16 at 16:20