Java Thread: Comparison of wait(), sleep() and join() methods


sleep() is a method which is used to hold the process for few seconds or the time you wanted but in case of wait() method thread goes in waiting state and it won’t come back automatically until we call the notify() or notifyAll().

The major difference is that wait() releases the lock or monitor while sleep() and join() doesn’t releases any lock or monitor while waiting. wait() is used for synchronizing the access for the shared object in multi-threaded environment and will be used in inter-threaded communication. sleep is used to pause the execution on currently thread for a defined time period.

Thread.sleep() sends the current thread into the “Not Runnable” state for some amount of time. The thread keeps the monitors it has acquired.

i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread. Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t.sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.

object.wait() sends the current thread into the “Not Runnable” state, like sleep(), but with wait() is called on an object, not a thread; we call this object the “lock object.”

Before lock.wait() is called, the current running thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the “wait list” associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.

thread.join() sends the current running thread into the “Not Runnable” state, until joined thread is completing its execution. once the joined thread completes its execution, the waiting thread will comes back to the runnable state. Then the waiting thread will be resumed again. join() method will not release any monitor or lock object acquired by the running thread and it will be waiting with those monitors(if there is any)

The wait() method must be called in a synchronized context, but sleep() and join() methods does not require to be.Thread.join() waits for the thread to completely finish, whereas a synchronized block can be used to prevent two threads from executing the same piece of code at the same time.

It is recommended, not use waitnotify or notifyAll on Thread instances. They should be used on objects for synchronizing the access among the multiple threads.


Lets compare each of these methods in detailed.

Derived from or Belongs to:

  • wait(): Object class
  • sleep(): Thread class
  • join():  Thread class

Call/Invoked on:

  • wait(): Call on an object; current thread must synchronize on the lock object.
  • sleep(): Call on a Thread; always currently executing thread will be sleep.
  • join():  Call on a Thread. currently executing thread will be joined at the end of the execution of the calling thread.

Synchronized Context:

  • wait(): must be called in a synchronized context. (either in synchronized block or method)
  • sleep(): synchronization context not required
  • join(): synchronization context not required

Hold lock/monitor:

  • wait(): release the object monitor for giving the chance for other threads to execute.
  • sleep(): keep object monitor for at least the timeout specified or somebody interrupt.
  • join(): keep the monitor and goes to sleep until the joined() method completes its execution.


  • wait():  Call notify(), notifyAll() on the object.
  • sleep():  After expiring the sleeping time or call interrupt().
  • join():  completing the run method of the joined thread (dead of the joined thread)


  • sleep():  for holding the execution of currently running thread for a specific time duration
  • wait(): for multi-thread-synchronization on an shared object.
  • join(): for joining the execution of the currently running thread at the end of the another thread.

What is really happening after waiting or sleeping?

sleep(), wait() and join() method will cause to move the currently running thread from running state to not runnable state (waiting/blocking/sleeping state) . However, the waiting/blocking thread will become runnable after expiring the time duration or calling the relevant method like notify(). notifyAll(), interrupt() etc.  what will be really happening after that?  Will the waiting thread get resumed/run as soon after it wakes up?

The simple answer is NO. The waiting thread will be moved from “Not runnable state” to “runnable state“. After that it is the responsibility of the Thread scheduler to move it to “running state“.  Since the Thread scheduler is working and shifting the execution of thread with milliseconds and nano seconds, we feel like that it just resumed as soon as  it wakes up.



5 thoughts on “Java Thread: Comparison of wait(), sleep() and join() methods


    Liked by 1 person


    Liked by 1 person


    Liked by 1 person

Leave a Reply


You are commenting using your account. Log Out /  Change )

Google photo


Twitter picture


Facebook photo


Connecting to %s