April 01, 2016

Part 3: Java Thread Interview Questions & Answers

What are the different states of a thread's lifecycle?
  • Runnable: waiting for its turn to be picked for execution by the thread scheduler based on thread priorities.
  • Running: The processor is actively executing the thread code. It runs until it becomes blocked, or voluntarily gives up its turn with this static method Thread.yield(). Because of context switching overhead, yield() should not be used very frequently.
  • Waiting: A thread is in a blocked state while it waits for some external processing such as file I/O to finish.
  • Sleeping: Java threads are forcibly put to sleep (suspended) with this overloaded method: Thread.sleep(milliseconds), Thread.sleep(milliseconds, nanoseconds);
  • Blocked on I/O: Will move to runnable after I/O condition like reading bytes of data etc changes.
  • Blocked on synchronization: Will move to Runnable when a lock is acquired.
  • Dead: The thread is finished working.
What is the difference between yield and sleeping?
Both yield and sleep are declared on java.lang.Thread class and doesn't release any lock held by the thread.

yield() method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.

sleep() allows the thread to go to sleep state for x milliseconds.

When a task invokes yield(), it changes from running state to runnable state. When a task invokes sleep(), it changes from running state to waiting/sleeping state.

How do you share data between two thread in Java?
wait and notify methods in Java are used for inter-thread communication i.e. if one thread wants to tell something to another thread, it uses notify() and notifyAll() method of java.lang.Object.

Classical example of wait and notify method is Producer Consumer design pattern, where One thread produce and put something on shared bucket, and then tell other thread that there is an item for your interest in shared object, consumer thread than pick item and do its job. Without wait() and notify(), consumer thread needs to be busy checking, even if there is no change in state of shared object.

This brings an interesting point on using wait and notify mechanism, a call to notify() happens, when thread changed state of shared object i.e. in this case producer change bucket from empty to not empty, and consumer change state from non-empty to empty.

Also wait and notify method must be called from synchronized context. A waiting thread may woke up, without any change in it's waiting condition due to spurious wake up. e.g: if a consumer thread, which is waiting because shared queue is empty, gets wake up due to a false alarm and try to get something from queue without further checking whether queue is empty or not than unexpected result is possible.

What is the difference between notify and notifyAll in Java?
notify will only notify one Thread and notifyAll method will notify all Threads  which are waiting on that monitor or lock.

When you call notify only one of waiting for the thread will be woken and it's not guaranteed which thread will be woken, it depends on upon Thread scheduler.

While if you call notifyAll method, all threads waiting on that lock will be woken up, but again all woken thread will fight for lock before executing remaining code. That's why wait is called on loop because if multiple threads are woken up, the thread which will get lock will first execute and it may reset waiting for condition, which will force subsequent threads to wait.

Why wait, notify and notifyAll are not inside thread class? 
Java provides lock at object level not at thread level that's why wait, notify and notifyAll methods are defined in Object class. Every object has lock, which is acquired by thread. Now if thread needs to wait for certain lock it make sense to call wait() on that object rather than on that thread.

Had wait() method declared on Thread class, it was not clear that for which lock thread was waiting. In short, since wait, notify and notifyAll operate at lock level, it make sense to defined it on object class because lock belongs to object.

Why wait and notify method are called from synchronized block?
Every object created in Java has one associated monitor (mutually exclusive lock). Only one thread can own a monitor at any given time.

For achieving synchronization in Java this monitor is used. When any thread enters a synchronized method/block it acquires the lock on the specified object. When any thread acquires a lock it is said to have entered the monitor. All other threads which need to execute the same shared piece of code (locked monitor) will be suspended until the thread which initially acquired the lock releases it.

wait method tells the current thread (thread which is executing code inside a synchronized method or block) to give up monitor and go to waiting state.

notify method wakes up a single thread that is waiting on this object's monitor, where as notifyAll method wakes up all the threads that called wait( ) on the same object.

Any method or a block of code, if not qualified with the keyword synchronized can be executed by more than one thread at any given time as object's monitor(lock) is not in the picture. Where as when a method is synchronized (or there is a synchronized block) only a single thread who has acquired the object's monitor can access the code.

Since wait method is about thread releasing the object's lock and go to waiting state, where as notify/notifyAll methods are about notifying the thread(s) waiting for the object's lock. So, wait(), notify() and notifyAll() methods (as mentioned above) should be invoked on an object only when the current thread has already acquired the lock on an object.

If you don't call them from synchronized context, your code will throw IllegalMonitorStateException. A more subtle reason is to avoid the race condition between wait and notify calls.

What is the difference between wait() and wait(long timeout)?
When wait() method is called on object, it causes causes the current thread to wait until another thread invokes the notify() or notifyAll() method for this object. wait(long timeout) causes the current thread to wait until either another thread invokes the notify() or notifyAll() methods for this object, or a specified timeout time has elapsed.

When wait() is called on object, Thread enters from running to waiting state. It waits for some other thread to call notify so that it could enter runnable state. When wait(long timeout) is called on object - Thread enters from running to waiting state. Than even if notify() or notifyAll() is not called after timeout time has elapsed thread will go from waiting to runnable state.

What is the difference between wait() and sleep()?
  • The wait() method belongs to java.lang.Object class, thus can be called on any Object. The sleep() method belongs to java.lang.Thread class, thus can be called on Threads.
  • The wait() method can only be called from Synchronized context i.e. using synchronized block or synchronized method. The sleep() method can be called from any context.
  • The wait() method releases the lock on an object and gives others chance to execute. The sleep() method does not releases the lock of an object for specified time or until interrupt.
  • A waiting thread can be awake by notify() or notifyAll() method. A sleeping can be awakened by interrupt or time expires.
Why Thread sleep() and yield() methods are static?
Thread sleep() and yield() methods work on the currently executing thread. So there is no point in invoking these methods on some other threads that are in wait state. That’s why these methods are made static so that when this method is called statically, it works on the current executing thread and avoid confusion to the programmers who might think that they can invoke these methods on some non-running threads.

How can we make sure main() is the last thread to finish in Java Program?
We can use Thread join() method to make sure all the threads created by the program is dead before finishing the main function.

How can you ensure all threads that started from main must end in order in which they started and also main should end in last?
We can use join() method to ensure all threads that started from main must end in order in which they started and also main should end in last.In other words waits for this thread to die. e.g:

public class MyJoinClass implements Runnable {
    public void run() {
        System.out.println("Inside run(), ThreadName=" + Thread.currentThread().getName());
    }

    public static void main(String... args) throws InterruptedException {
        System.out.println("main() started");
        MyJoinClass runnable = new MyJoinClass();
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);

        thread1.start();
        thread1.join();

        thread2.start();
        thread2.join();

        System.out.println("main() ended");
    }
}

With Join:
main() started
Inside run(), ThreadName=Thread-5
Inside run(), ThreadName=Thread-6
main() ended

Without Join:
main() started
Inside run(), ThreadName=Thread-5
main() ended
Inside run(), ThreadName=Thread-6

ALSO CHECKAll About Java Threads

-K Himaanshu Shuklaa..

No comments:

Post a Comment

RSSChomp Blog Directory