Thursday, November 2, 2017

Prefer TimeUnit Sleep over Thread.Sleep - Java Coding Tips

What is TimeUnit in Java
in Java is a class on java.util.concurrent package, introduced in Java 5 along with CountDownLatch, CyclicBarrier, Semaphore, and several other concurrent utilities. TimeUnit provides a human-readable version of the Thread.sleep() method which can be used in place of the former. For a long time Thread's sleep() method is a standard way to pause a Thread in Java and almost every Java programmer is familiar with that. In fact, the sleep method itself is very popular and has appeared on many Java interviews. The difference between wait and sleep is one of the tough Java questions to answer. 

If you have used Thread.sleep() before and I am sure you do, you might be familiar with a fact like it's a static method, it doesn't release the lock when pausing Thread and it throws InterruptedException

But what many of us don't consider a potential issue is a readability. Thread.sleep() is an overloaded method and accept long millisecond and long nanosecond, which makes it hard for programmers to find out exactly how many seconds, minutes, hours or day current Thread is sleeping. 

Btw, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at the Java Multithreading, Concurrency, and Performance Optimization course by Michael Pogrebinsy on Udemy. It's an advanced course to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance

TimeUnit.sleep() vs Thread.sleep() - Which one is more readable?

Look at below example of Thread's sleep() method:


By just having a cursory glance, can you figure out how long current Thread will wait? Some of you may be but its hardly readable for many Java programmers and you need to convert milliseconds further into seconds and then into minutes. 

Let's take a look at another example of Thread.sleep() method which is slightly more readable than the previous example.


This is much better than the previous one but still, it's not perfect, and until you are aware that sleep times are in millisecond its not easy to guess that current Thread will wait for 4 minutes.

The TimeUnit class resolves this issue by providing an indicator for DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, and NANOSECONDS. java.util.concurrent.TimeUnit is a perfect example of powerful Java Enum

All TimeUnit is Enum instances. Let's see how to sleep Thread for 4 minutes using TimeUnit :

TimeUnit.MINUTES.sleep(4);  // sleeping for 4 minutes

Similarly, you can introduce pauses on seconds, minutes and hour level. By looking at this code you can find out that, this is much more readable than Thread's sleep method. Remember that TimeUnit.sleep() internally calls Thread.sleep() for sleeping and throws InterruptedException

You can also check the JDK code to verify that. 

Java Program to use TimeUnit.sleep() method

Here is a sample code example that demonstrates how to use TimeUnit's sleep() method in Java.

 * Java program to demonstrate how to use the TimeUnit.sleep()
   method in Java
 * TimeUnit is a new way of introducing pause in Java program.
 * @author Javin

public class TimeUnitTest {

    public static void main(String args[]) throws InterruptedException {

        System.out.println("Sleeping for 4 minutes using Thread.sleep()");
        Thread.sleep(4 * 60 * 1000);
        System.out.println("Sleeping for 4 minutes using TimeUnit sleep()");

Apart from sleep() functionality, TimeUnit also provide convenient method to convert time into different Unit. For example if you want to convert seconds into milliseconds than you can use following code :


It will return 44,000. It's readable and convenient way to convert time into different unites e.g. micro seconds, Milli seconds etc.

TimeUnit vs Thread.sleep()

What is TimeUnit class in Java programmingSo far we have discussed benefit of using TimeUnit to improve readability but some time it turns out other way as well. Since Thread.sleep() is been around for years, almost every Java programmer knows about it and by looking Thread.sleep() they come to know that Thread is going to pause. This is not true with TimeUnit class, with two reason first its not very popular at least compare to Thread.sleep() and second it's not in Thread class, much like wait and notify which are also not in Thread class.. Anyway none of these are big issues and it will take some time to be adopted and become an standard way, given the size of Java community around the world.

In Summary prefer TimeUnit.sleep() method if you would like to introduce short pause in your program and other places where you think of Thread.sleep(). It not only improves readability of code but also makes you familiar with java.util.concurrent package, which is key API for concurrent programming in Java.

Further Learning
Multithreading and Parallel Computing in Java
Java Concurrency in Practice - The Book
Applying Concurrency and Multi-threading to Common Java Patterns
Java Concurrency in Practice Course by Heinz Kabutz

Other multi-threading and concurrency tutorials from Javarevisited


Anonymous said...

TimeUnit.MINUTES.sleep(4); // sleeping for 1 minutes

should be:

TimeUnit.MINUTES.sleep(4); // sleeping for 4 minutes

Anonymous said...

Java 5 only introduced some of the enumeration. Java 6 introduced MINUTES, HOURS, DAYS along with related methods.

Anonymous said...

TimeUnit calls Thread.sleep() so it's not much of a difference...

Anonymous said...

It is all about readability, that is the point of the article.

Anonymous said...

TimeUnit.sleep(0) does not behave like Thread.sleep(0). Is that intentional?

Anonymous said...

One reason to prefer TimeUnit's sleep() method is readability other could be that Thread.sleep(0) is not clearly defined across platforms. In TimeUnit it does nothing

Unknown said...

TimeUnit.sleep( internally calls thread.sleep. no much difference
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns);

Post a Comment