Why Thread.sleep is bad to use
Asked Answered
G

2

47

Apologies for this repeated question but I haven't found any satisfactory answers yet. Most of the question had their own specific use case:
Java - alternative to thread.sleep
Is there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?

My question is for the very generic use case. Wait for a condition to complete. Do some operation. Check for a condition. If the condition is not true, wait for some time and again do the same operation.

For e.g. Consider a method that creates a DynamoDB table by calling its createAPI table. DynamoDB table takes some time to become active so that method would call its DescribeTable API to poll for status at regular intervals until some time(let's say 5 mins - deviation due to thread scheduling is acceptable). Returns true if the table becomes active in 5 mins else throws exception.

Here is pseudo code:

public void createDynamoDBTable(String name) {
  //call create table API to initiate table creation

  //wait for table to become active
  long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE;

  while(System.currentTimeMillis() < endTime) {
    boolean status =  //call DescribeTable API to get status;
    if(status) {
         //status is now true, return
         return
    } else {
        try {
            Thread.sleep(10*1000);
        } catch(InterruptedException e) {
        }
    }
  }

  throw new RuntimeException("Table still not created");
}

I understand that by using Thread.sleep blocks the current thread, thereby consuming resources. but in a fairly mid size application, is one thread a big concern?
I read somewhere that use ScheduledThreadPoolExecutor and do this status polling there. But again, we would have to initialize this pool with at least 1 thread where runnable method to do the polling would run.

Any suggestions on why using Thread.sleep is said to be such a bad idea and what are the alternative options for achieving same as above.

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

Glib answered 24/7, 2013 at 6:25 Comment(7)
msmvps.com/blogs/peterritchie/archive/2007/04/26/…Decrescent
Your link is about .Net. It doesn't apply to Java.Crosswise
Polling is bad, no doubt. But if you don't have alternatives, it is the least thing you should care about.Damages
@StinePike, Is that supposed to mean, Answer lies in the blog? I have gone through the post but didn't see any thing in particular apart from resource blocking (already mentioned) and this The thread needs perform logic every n milliseconds As noted earlier, Sleep means relinquish control. When your thread gets control again isn't up to the thread; so it can't be used for periodic logic. But I assume, he is talking about scheduling exactly after n milliseconds.Glib
whoever voted as 'Too broad' please let me know how can I make it more specific? I have pretty much asked about use case of method in question.Glib
Using Thread.sleep() is okay in certain situations (see accepted answer, for example). But you should never catch and ignore the InterruptedException!Rawley
so Thread.sleep() is okay to use if you want to sync notification/update from your API right?Tyro
M
54

It's fine to use Thread.sleep in that situation. The reason people discourage Thread.sleep is because it's frequently used in an ill attempt to fix a race condition, used where notification based synchronization is a much better choice etc.

In this case, AFAIK you don't have an option but poll because the API doesn't provide you with notifications. I can also see it's an infrequent operation because presumably you are not going to create thousand tables.

Therefore, I find it fine to use Thread.sleep here. As you said, spawning a separate thread when you are going to block the current thread anyways seems to complicate things without merit.

Moncton answered 24/7, 2013 at 6:44 Comment(3)
One big caveat: make sure that the sleeping thread isn't holding onto scarce resources, like a mutex or database connection.Calendula
Would this pattern be also acceptable in following case? - Polling SQS for one message at a time and maintaining a list of messages. When size of list reaches X number, process them in bulk. If there are no more messages in SQS, sleep for some time. Again poll after that.Glib
@Jitendra: Usually with MQs you'd want avoid polling, but AFAIK there is no other way than to poll in SQS (which by the way they charge for even when there is no message), so Thread.sleep is an option. I might be inclined to use scheduled executor though because it makes it easy to add consumers, finetune the scheduling of polling and forces you to separate business logic and infrastructure.Moncton
K
19

Yes, one should try to avoid usage of Thread.sleep(x) but it shouldn't be totally forgotten:

Why it should be avoided

  • It doesn't release the lock
  • It doesn't gurantee that the execution will start after sleeping time (So it may keep waiting forever - obviously a rare case)
  • If we mistakenly put a foreground processing thread on sleep then we wouldn't be able to close that application till x milliseconds.
  • We now full loaded with new concurrency package for specific problems (like design patterns (ofcourse not exactly), why to use Thread.sleep(x) then.

Where to use Thread.sleep(x):

  • For providing delays in background running threads
  • And few others.
Koffler answered 15/3, 2017 at 17:11 Comment(1)
Can you explain few others? btw great answer.Coexist

© 2022 - 2024 — McMap. All rights reserved.