Tuesday, August 6, 2013

THREAD SLEEP/WAIT

Oxford Dictionary defines wait and sleep as below:
wait: delay action until (someone) arrives or is ready.
sleep: a condition of body and mind which typically recurs for several hours every night, in which the nervous system is relatively inactive and consciousness practically suspended
Wait is to not act till someone arrives. Sleep is to not act for a specified time. It’s amazing how much dictionary meaning of words can tell you about their technical aspects.
Wait and Sleep are confusing terms. A wife falls asleep waiting for the husband to be back from office. Isn’t sleep just a wait to wake up again. Aren’t they interchangeable terms? Which holds lock on the monitors? Which consumes CPU cycles? Lets’s explore.
One important concept to be understood before moving forward is Context Switching: When multiple processes share a single CPU, they fight for the CPU time. It is via context switching that each of them gets some CPU time slice. In very basic terms, one process should be switched out of CPU so that another process can run. Similar context switching can be understood at the JVM level for a single process which has many threads.
To begin with we need to define, the States of a Thread in Java.
  1. RUNNABLE: Thread executing in JVM (might not execute in OS, as OS might make it wait for the processor, say)
  2. WAITING: Waiting ad infinitum for some other thread to perform some action. If current Thread callsObject.wait(), it is WAITING for some other thread to call Object.notify().
  3. BLOCKED: Waiting to get monitor lock
    • Either waiting to enter synchronized block, or
    • In Waiting state of Current Thread, if some other thread calls Object.notify(), the Current Thread moves to BLOCKED state and fights for the monitor lock. If some other Thread gets the lock, current Thread goes back to WAITING state.)
  4. TIMED_WAITING: 
    • Waiting for a specified time interval (Thread.sleep(TIMEOUT)) or
    • Waiting for some other Thread to call Object.notify() or for a specified time interval, whichever is shorter (Object.wait(TIMEOUT)).
What happens when Thread.sleep(TIMEOUT) is called? TIME-SYNCHRONIZATION
  1. The running Thread is forcefully switched out (context switching) and put in TIMED_WAITING state for the specified interval.
  2. As name suggests, it simply sleeps and require no CPU time-slice. Theoretically speaking, if this is the only process running and you put Sleep statements with substantial TIMEOUT, you will notice drop in CPU usage. Short bursts of continuous sleep statements, might increase CPU usage as Context Switching incurs its own cost.
  3. Once the Sleep time is over, Thread is scheduled back to be executed. However there is no guarantee that  Context Switching will happen immediately. Depends upon the resources available. If a high priority work is going on, this Thread will not get CPU time instantaneously. If will be scheduled no doubt, but when it will be executed comes with no guarantee.
  4. Sleep can be interrupted by Thread.interrupt(). This caused InterruptedException to be thrown. It is normally used to HALT the operations.
  5. If sleep is called from a synchronized block (say). No other Thread can enter this block. Thread holds the ownership (lock) of the monitor object.
  6. sleep is a static method. If we call diffThread.sleep from the current Thread, it wont halt diffThread. It is the current Thread which will sleep.
What happens when Object.wait() is called from inside the synchronized block? MULTI-THREAD SYNCHRONIZATION
  1. The running Thread is switched out (context switching) and goes to the WAITING state .  In WAITING state, itrequires no CPU time-slice.
  2. In Java every Object is associated with two queues, wait queue and entry queue. Post Object.wait() Thread waits on the wait queue of the object.
  3. The Thread will hold no lock on the monitor object. Any other thread can enter the synchronized block.
  4. It will remain in WAITING state until some other Thread which will synchronize on the same object, calls Object.notify()
  5. Once Object.notify() is called, of all Threads that are WAITING on the same monitor object, one is awakened at random and is moved to BLOCKED state (Moved from waiting queue of object to entry queue of the object), where it tries to get the lock on monitor object. It has to fight with other Threads BLOCKED on the same Object. Once it gets the lock, it is scheduled to be executed by the CPU, again with no guarantees when.
  6. If 10 Threads have called Object.wait() on the same object, Object.notifyAll(), awakens all 10 threads and move them in BLOCKED state where they fight with other BLOCKED Threads for the lock on the object  One of these 10 might get the lock (some other Thread which was BLOCKED to enter the  synchronized block, might just get the lock) and rest 9 go back to the WAITING state (in effect waiting Queue of the Object) till they get the next notify signal.
  7. In BLOCKED state Thread incurs CPU cost as it tries to get the lock. JVM might try to get to acquire monitor lock multiple times before context switching it OR JVM might context switch it just after one try. It depends on Algorithm implemented at JVM level.

No comments:

Post a Comment