ForeverStudent
ForeverStudent

Reputation: 2537

is Thread.sleep() guaranteed to wait?

Consider this scenario: I want to make several web service calls consecutively. I am only allowed to make a call every 10 seconds. I have something like this:

while(true) //we will break inside the loop eventually
{
           //...
    try {
          Thread.sleep(10000);
        } 
    catch(InterruptedException e) 
        {
           e.printStackTrace();
        }
     //make web service call here
     //...
}

As you can see, This will (hopefully) make a call approximately every 10 seconds. But my concern is that while Thread.sleep() is executing, I will get interrupted before 10 seconds and I will subsequently make a web service call that will get ignored.

This is not a multithreaded application so it runs on its own JVM. This is the only thread I am not calling interrupt() on this thread from anywhere, but I am not sure if I will run into trouble with my host machine's thread scheduler or anything.

Accuracy of timekeeping is not of great importance. I especially don't care if the 10 seconds turns into 15 seconds. But if somehow Thread.Sleep throws too soon I will be in trouble.

Is this the proper way of implementing this behaviour?

To clarify:

1- this is NOT a multi-threaded program

2- I do NOT want to do a exact times, the timing can be inaccurate as long as an unexpected exception does not get me out of the try block prematurely

Upvotes: 2

Views: 1927

Answers (2)

Raedwald
Raedwald

Reputation: 48682

No, it is not guaranteed to wait for at least 10 seconds. The whole point of the sleep method throwing the checked exception InterruptedException is the possible need to end the sleep before the 10 seconds are up, by interrupting the thread.

You are wrong to focus on your program being "single threaded". In practice there is no such thing: the JVM and the JRE are permitted (and in fact do) run additional threads. The Thread.sleep() API says that the method throws InterruptedException if the sleeping thread is interrupted by another thread; it does not specify that only "user" threads are permitted to interrupt the sleeping thread.

Upvotes: 0

erickson
erickson

Reputation: 269717

I am not sure if I will run into trouble with my host machine's thread scheduler

No, the runtime will not interrupt an application thread for any reason. Only other code in your application (or code that you drag in with some framework that you choose) will interrupt threads.

Every task should specify an interruption policy: what will happen if the thread is interrupted? An application should never interrupt a thread without understanding its interrupt policy and being prepared to deal with the consequences.

So, define the interrupt policy for your thread. In your application, it is something you don't expect to happen, and if someone adds code to your application that calls interrupt() on your thread, they introduced a bug. Basically, your policy is that interruption isn't allowed. So, throwing a some unchecked exception, like IllegalStateException is a valid response.

Is this the proper way of implementing this behaviour?

No, it's not. When you are interrupted, you should signal callers that you were interrupted. This should be done by letting an InterruptedException propagate back to the caller (or a application-defined exception with similar meaning), or by restoring the interrupt status on the current thread. Suppose your interruption policy permits interruption, by terminating the loop prematurely. You should still restore the interrupt status:

while(true) {
  ...
  try {
    Thread.sleep(10000);
  } catch(InterruptedException abort) {
    Thread.currentThread().interrupt();
    break;
  }
  /* Make web service call here... */
}

Upvotes: 1

Related Questions