Monday, June 11, 2012

Java multithreading interview questions and answers

Q. What is the difference between processes and threads?
A. A process is an execution of a program but a thread is a single execution sequence within the process. A process can contain multiple threads. A thread is sometimes called a lightweight process.


A JVM runs in a single process and threads in a JVM share the heap belonging to that process. That is why several threads may access the same object. Threads share the heap and have their own stack space. This is how one thread’s invocation of a method and its local variables are kept thread safe from other threads. But the heap is not thread-safe and must be synchronized for thread safety.

Q. Explain different ways of creating a thread?
A. Threads can be used by either
  • Extending the Thread class.
  • Implementing the Runnable interface.
  • Using the Executor framework (this creates a thread pool) 













class Counter extends Thread {
    
    //method where the thread execution will start
    public void run(){
        //logic to execute in a thread   
    }
    //let’s see how to start the threads
    public static void main(String[] args){
       Thread t1 = new Counter();
       Thread t2 = new Counter();
       t1.start();  //start the first thread. This calls the run() method.
       t2.start(); //this starts the 2nd thread. This calls the run() method. 
    }


class Counter extends Base implements Runnable{
   
    //method where the thread execution will start
    public void run(){
        //logic to execute in a thread   
    }
    //let us see how to start the threads
    public static void main(String[] args){
         Thread t1 = new Thread(new Counter());
         Thread t2 = new Thread(new Counter());
         t1.start();  //start the first thread. This calls the run() method.
         t2.start();  //this starts the 2nd thread. This calls the run() method. 
    }

The thread pool is more efficient and  learn why and how to create pool of  threads using the executor framework.

Q. Which one would you prefer and why?
A. The Runnable interface is preferred, as it does not require your object to inherit a thread because when you need multiple inheritance, only interfaces can help you. In the above example we had to extend the Base class so implementing Runnable interface is an obvious choice. Also note how the threads are started in each of the different cases as shown in the code sample. In an OO approach you should only extend a class when you want to make it different from it’s superclass, and change it’s behavior. By implementing a Runnable interface instead of extending the Thread class, you are telling to the user that the class Counter is an object of type Base and will run as a thread.

Q. Briefly explain high-level thread states?
A. The state chart diagram below describes the thread states.


  • Runnable — A thread becomes runnable when you call the start( ), but does  not necessarily start running immediately.  It will be pooled waiting for its turn to be picked for execution by the thread scheduler based on thread priorities.

    ?
    1
    2
    MyThread aThread = new MyThread();
    aThread.start();                   //becomes runnable
  • 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.A call to currObject.wait( ) method causes the current thread to wait until some other thread invokes currObject.notify( ) or the currObject.notifyAll( ) is executed.
  • 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.
Thread.State enumeration contains the possible states of a Java thread in the underlying JVM.

Q. What is the difference between yield and sleeping? What is the difference between the methods sleep( ) and wait( )?
A. 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.

The method wait(1000), causes the current thread to sleep up to one second. A thread could sleep less than 1 second if it receives the notify( ) or notifyAll( ) method call. The call to sleep(1000) causes the current thread to sleep for 1 second.

Q. How does thread synchronization occurs inside a monitor? What levels of synchronization can you apply? What is the difference between synchronized method and synchronized block?
A. In Java programming, each object has a lock. A thread can acquire the lock for an object by using the synchronized keyword. The synchronized keyword can be applied in method level (coarse grained lock – can affect performance adversely) or block level of code (fine grained lock). Often using a lock on a method level is too coarse. Why lock up a piece of code that does not access any shared resources by locking up an entire method. Since each object has a lock, dummy objects can be created to implement block level synchronization. The block level is more efficient because it does not lock the whole method.


The JVM uses locks in conjunction with monitors. A monitor is basically a guardian who watches over a sequence of synchronized code and making sure only one thread at a time executes a synchronized piece of code. Each monitor is associated with an object reference. When a thread arrives at the first instruction in a block of code it must obtain a lock on the referenced object. The thread is not allowed to execute the code until it obtains the lock. Once it has obtained the lock, the thread enters the block of protected code. When the thread leaves the block, no matter how it leaves the block, it releases the lock on the associated object.

No comments:

Post a Comment