Saturday, 1 August 2015

Thread interview question and answer

Threads VS Process
1. Threads share the address space of the process that created it; processes have their own address.

2. Threadshave direct access to the data segment of its process; processes have their own copy of the data segmentof the parent process.

3. Threads can directly communicate with other threads of its process; processes must use inter process communication to communicate with sibling processes.

4.Threads have almost no overhead; processes have considerable overhead.

5.New threads are easily created; new processes require duplication of the parent process.

6. Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.

7.Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process do not affect child processes.

Life Cycle of a Thread





Life Cycle of a Thread Difference in start() and run()
When program calls start() method a new Thread is created and code inside run() method is executed in new Thread while if you call run() method directly no new Thread is created and code inside run() will execute on current Thread.

What is synchronization in respect to multi-threading in Java?
With respect to multi-threading, synchronization is the capability to control the access of multiple threads to shared resources. Without synchronization, it is possible for one Java thread to modify a shared variable while another thread is in the process of using or updating it.

· Only methods can be synchronized, classes/ variables/ constructors cannot.

·All methods in a class need not be synch, a class can have both synch and non-synch methods

·If a thread goes to sleep having lock with it then it doesn’t release it while asleep


Race Condition
A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, you don't know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are "racing" to access/change the data.

In order to prevent race conditions from occurring, you would typically put a lock around the shared data to ensure only one thread can access the data at a time.

LiveLock
Livelock occurs when all threads are blocked, or are otherwise unable to proceed due to unavailability of required resources, and the non-existence of any unblocked thread to make those resources available. In terms of Java API, thread livelock can occur in following conditions:

· When all the threads in a program execute Object.wait(0) on an object with zero parameter. The program is live-locked and cannot proceed until one or more threads call Object.notify() or Object.notifyAll() on the relevant objects.

·When all the threads in a program are stuck in infinite loops.

Starvation
If a thread is not granted CPU time because other threads grab it, it is called "starvation". The thread is "starved to death" because other threads are allowed the CPU time instead of it. The solution to starvation is called "fairness" - that all threads are fairly granted a chance to execute.

Deadlock in threads
Deadlock occurs when two threads have a circular dependency on a pair of synchronized objects. Suppose, Thread A is having lock on Object X and Thread B is having lock on Object Y. Now, A won’t release X until it gets Y and B won’t release Y until it gets a hold on object X so a deadlock situation arises.


How to find whether a deadlock has occurred in Java? How to detect a Deadlock in Java?

Since JDK 1.5 there are some powerful methods added in the java.lang.management package to diagnose and detect deadlocks. The java.lang.management.ThreadMXBeaninterface is management interface for the thread system of the Java virtual machine. It has two methods to detect deadlock in a Java application

·  findMonitorDeadlockedThreads() – This method can be used to detect cycles of threads that are in deadlock waiting to acquire object monitors. It returns an array of thread IDs that are deadlocked waiting on monitor.

· findDeadlockedThreads() – It returns an arrayof thread IDs that are deadlocked waiting on monitor or ownable synchronizers.

What is a thread leak?
Thread leak is when an application does not release references to a thread object properly. Due to this some Threads do not get garbage collected and the number of unused threads grows with time.
Thread leak can often cause serious issues on a Java application since over a period of time too many threads will be created but not released and may cause applications to respond slow or hang.

What is volatile keyword in Java?
When we use volatile keyword with a variable, all the threads read its value directly from the memory and doesn’t cache it. This makes sure that the value read is the same as in the memory.

What is context-switching in multi-threading?
Context Switching is the process of storing and restoring of CPU state so that Thread execution can be resumed from the same point at a later point of time. Context Switching is the essential feature for multitaskingoperating system and support for multi-threaded environment.

Preemptive scheduling vs. time slicing?
In preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence. 

In time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks. 


The scheduler then determines which task should execute next, based on priority and other factors


What are the two ways of creating thread?
There are two ways to create a new thread.
Extend the Thread class and override the run() method in your class. Create an instance of the subclass and invoke the start() method on it, which will create a new thread of execution. 

e.g.

public class NewThread extends Thread{
public void run(){
// the code that has to be executed in a separate new thread goes here
}
public static void main(String [] args){
NewThread c = new NewThread();
c.start();
}

 }
Implements the Runnable interface. The class will have to implement the run() method in the Runnable interface. Create an instance of this class. Pass the reference of this instance to the Thread constructor a new thread of execution will be created. e.g. class
public class NewThread implements Runnable{
public void run(){
// the code that has to be executed in a separate new thread goes here
}
public static void main(String [] args){
NewThread c = new NewThread();
Thread t = new Thread(c);
t.start();

}

What is the difference when the synchronized keyword is applied to a static method or to a non static method?

When a synch non static method is called a lock is obtained on the object. When a synch static method is called a lock is obtained on the class and not on the object. The lock on the object and the lock on the class don’t interfere with each other. It means, a thread accessing a synch non static method, and then the other thread can access the synch static method at the same time but can’t access the synch non static method.


Which is more preferred – Synchronized method or synchronized block?

Synchronized block is more preferred way because it doesn’t lock the Object, synchronized methods lock the Object and if there are multiple synchronization blocks in the class, even though they are not related, it will stop them from execution and put them in wait state to get the lock on Object.


Difference in yield and join

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.
join() If any executing thread t1 calls join() on t2 i.e.; t2.join() immediately t1 will enter into waiting state until t2 completes its execution.


What is Java Thread Dump, How can we get Java Thread dump of a Program?

Thread dump is list of all the threads active in the JVM, thread dumps are very helpful in analyzing bottlenecks in the application and analyzing deadlock situations. There are many ways using which we can generate Thread dump – Using Profiler, Kill -3 command, jstack tool etc.


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.


Volatile keyword in java

Each thread has its own stack, and so its own copy of variables it can access. When the thread is created, it copies the value of all accessible variables in its own memory. The volatile keyword is used to say to the JVM "Warning, this variable may be modified in another Thread". The volatile forces the thread to update the original variable for each variable.

Thread Local

Thread Local can be considered as a scope of access, like a request scope or session scope. It's a thread scope. You can set any object in Thread Local and this object will be global and localto the specific thread which is accessing this object


·Values stored in Thread Local are global to the thread, meaning that they can be accessed from anywhere inside that thread. If a thread calls methods from several classes, then all the methods can see the Thread Local variable set by other methods (because they are executing in same thread)

·Values stored in Thread Local are local to the thread, meaning that each thread will have its own Thread Local variable. One thread cannot access/modify other thread's Thread Local variables.

·ThreadLocal in Java is a different way to achieve thread-safety, it doesn't address synchronization requirement, instead it eliminates sharing by providing explicitly copy of Object to each thread

·ThreadLocal are visible only in Single Thread. No two Thread can see each other’s ThreadLocal variable

Green Thread VS Native Thread
Both are ways of achieving a ‘multi-threaded program’


·A native thread uses the operating systems threading capability to execute multi-threaded programs. On the other hand, the green threads emulates the multi-threading without using the underlying capabilities of the OS.

·Another advantage of native threads is that multiple processes would execute in parallel in a multi-core machine. On the other hand, green threads are executed on a single core the entire time and it is the VM that gives a multi-threading notion. So actually there is only singe executing in case of green threads.

·Native threads uses OS scheduling algorithm. Modern day OSes support pre-emptive scheduling. Green threads can use any kind of scheduling algorithm. Synchronization and Resource sharing

·Green threads are scheduled by a virtual machine; native threads are scheduled by an operational system.

· Green Threads were used earlier in Java1.3

Why wait(), notify() and notifyAll() methods have to be called from synchronized method or block?

When a Thread calls wait() on any Object, it must have the monitor on the Objectthat it will leave and goes in wait state until any other thread call notify() on this Object. Similarly when a thread calls notify() on any Object, it leaves the monitor on the Object and other waiting threads can get the monitor on the Object. Since all these methods require Thread to have the Object monitor, that can be achieved only by synchronization, they need to be called from synchronized method or block.


Difference in wait() and sleep()
Wait()
Sleep()
Can be woken up by another process calling notify() or notifyall() on the monitor Cannot be woken up
wait (and notify) must happen in a block synchronized on the monitor Does not
Called on a Object Called on Thread
waiting releases the lock on the object sleeping a Thread does not release the locks it holds
wait() is used for multi-thread-synchronization. sleep()is used for time-syncronization
In sleep() the thread stops working for the specified duration In wait() the thread stops working until the object being waited-on is notified

Thread Pool

Thread Pools are useful when you need to limit the number of threads running in your application at the same time. There is a performance overhead associated with starting a new thread, and each thread is also allocated some memory for its stack etc.

Instead of starting a new thread for every task to execute concurrently, the task can be passed to a thread pool. As soon as the pool has any idle threads the task is assigned to one of them and executed. Internally the tasks are inserted into a Blocking Queue which the threads in the pool are dequeuing from. When a new task is inserted into the queue one of the idle threads will dequeue it successfully and execute it. The rest of the idle threads in the pool will be blocked waiting to dequeue tasks.

Thread pools are often used in multi threaded servers. Each connection arriving at the server via the network is wrapped as a task and passed on to a thread pool. The threads in the thread pool will process the requests on the connections concurrently.

Java 5 comes with built in thread pools in the java.util.concurrent package, so you don't have to implement your own thread pool.

java.util.concurrent package

Java 5 added a new Java package to the Java platform, the java.util.concurrent package. This package contains a set of classes that makes it easier to develop concurrent (multithreaded) applications in Java:


§  BlockingQueue

o   ArrayBlockingQueue

o   DelayQueue

o   LinkedBlockingQueue

o   PriorityBlockingQueue

o   SynchronousQueue

§  BlockingDeque

o   LinkedBlockingDeque

§  ConcurrentMap

§  ConcurrentNavigableMap

§  CountDownLatch

§  CyclicBarrier

§  Exchanger

§  Semaphore

§  ExecutorService

o  ThreadPoolExecutor

§  ScheduledExecutorService

§  Lock

BlockingQueue Usage

A BlockingQueue is typically used to have on thread produce objects, which another thread consumes. Here is a diagram that illustrates this principle:



A BlockingQueue with one thread putting into it, and another thread taking from it.
The producing thread will keep producing new objects and insert them into the queue, until the queue reaches some upper bound on what it can contain. If the blocking queue reaches its upper limit, the producing thread is blocked while trying to insert the new object. It remains blocked until a consuming thread takes an object out of the queue.

The consuming thread keeps taking objects out of the blocking queue, and processes them. If the consuming thread tries to take an object out of an empty queue, the consuming thread is blocked until a producing thread puts an object into the queue.

It is not possible to insert null into a BlockingQueue. If you try to insert null, the BlockingQueue will throw a NullPointerException.

ArrayBlockingQueue :It’s a bounded, blocking queue that stores the elements internally in an array. That it is bounded means that it cannot store unlimited amounts of elements. There is an upper bound on the number of elements it can store at the same time. You set the upper bond at instantiation time, and after that it cannot be changed.

The ArrayBlockingQueue stores the elements internally in FIFO (First In, First Out) order.

The DelayQueue keeps the elements internally until a certain delay has expired

The LinkedBlockingQueue keeps the elements internally in a linked structure (linked nodes). This linked structure can optionally have an upper bound if desired. If no upper bound is specified, Integer.MAX_VALUE is used as the upper bound. The LinkedBlockingQueue stores the elements internally in FIFO (First In, First Out) order.

The PriorityBlockingQueue is an unbounded concurrent queue. It uses the same ordering rules as the java.util.PriorityQueue class. You cannot insert null into this queue.

All elements inserted into the PriorityBlockingQueue must implement the java.lang.Comparable interface. The elements thus order themselves according to whatever priority you decide in your Comparable implementation

SynchronousQueue is a queue that can only contain a single element internally. A thread inserting an element into the queue is blocked until another thread takes that element from the queue. Likewise, if a thread tries to take an element and no element is currently present, that thread is blocked until a thread inserts an element into the queue

The BlockingDeque

The BlockingDeque class is a Deque which blocks threads trying to insert or remove elements from the deque, in case it is either not possible to insert or remove elements from the deque.

A deque is short for "Double Ended Queue". Thus, a deque is a queue which you can insert and take elements from, from both ends.

A BlockingDeque could be used if threads are both producing and consuming elements of the same queue. It could also just be used if the producing thread needs to insert at both ends of the queue, and the consuming thread needs to remove from both ends of the queue. Here is an illustration of that:




A BlockingDeque - threads can put and take from both ends of the deque.
A thread will produce elements and insert them into either end of the queue. If the deque is currently full, the inserting thread will be blocked until a removing thread takes an element out of the deque. If the deque is currently empty, a removing thread will be blocked until an inserting thread inserts an element into the deque.

The LinkedBlockingDeque is a Deque which will block if a thread attempts to take elements out of it while it is empty, regardless of what end the thread is attempting to take elements from.

ConcurrentHashMap

The ConcurrentHashMapis very similar to the java.util.HashTable class, except that ConcurrentHashMap offers better concurrency than HashTable does. ConcurrentHashMap does not lock the Map while you are reading from it. Additionally, ConcurrentHashMap does not lock the entire Map when writing to it. It only locks the part of the Map that is being written to, internally.

Another difference is that ConcurrentHashMap does not throw ConcurrentModificationException if the ConcurrentHashMap is changed while being iterated. The Iterator is not designed to be used by more than one thread though.

CountDownLatch is initialized with a given count. This count is decremented by calls to the countDown() method. Threads waiting for this count to reach zero can call one of the await() methods. Calling await() blocks the thread until the count reaches zero.

CyclicBarrierclass is a synchronization mechanism that can synchronize threads progressing through some algorithm. In other words, it is a barrier that all threads must wait at, until all threads reach it, before any of the threads can continue. Here is a diagram illustrating that:




Two threads waiting for each other at CyclicBarriers.
The threads wait for each other by calling the await() method on the CyclicBarrier. Once N threads are waiting at the CyclicBarrier, all threads are released and can continue running.

Exchanger class represents a kind of rendezvous point where two threads can exchange objects.

An exchanger (also known as a rendezvous) is a thread-synchronization construct that lets a pair of threads exchange data items. An exchanger is similar to a cyclic barrier whose count is set to 2 but also supports exchange of data when both threads reach the barrier.




Semaphore class is a counting semaphore. That means that it has two main methods:
acquire(), release()

The counting semaphore is initialized with a given number of "permits". For each call to acquire() a permit is taken by the calling thread. For each call to release() a permit is returned to the semaphore. Thus, at most N threads can pass the acquire() method without any release() calls, where N is the number of permits the semaphore was initialized with. The permits are just a simple counter. Nothing fancy here.

Semaphore Usage: As semaphore typically have two uses:


·Guarding Critical Sections: If you use a semaphore to guard a critical section, the thread trying to enter the critical section will typically first try to acquire a permit, enter the critical section, and then release the permit again after

·Sending Signals Between Threads: If you use a semaphore to send signals between threads, then you would typically have one thread call the acquire() method, and the other thread to call the release() method.

Fairness: No guarantees are made about fairnessof the threads acquiring permits from the Semaphore i.e. there is no guarantee that the first thread to call acquire() is also the first thread to obtain a permit. If the first thread is blocked waiting for a permit, then a second thread checking for a permit just as a permit is released, may actually obtain the permit ahead of thread 

1.If you want to enforce fairness, the Semaphore class has a constructor that takes a boolean telling if the semaphore should enforce fairness. Enforcing fairness comes at a performance / concurrency penalty, so don't enable it unless you need it.

ExecutorServiceinterface represents an asynchronous execution mechanism which is capable of executing tasks in the background. An ExecutorService is thus very similar to a thread poolTask Delegation.




Once the thread has delegated the task to the ExecutorService, the thread continues its own execution independent of the execution of that task.

ThreadPoolExecutor is an implementation of the ExecutorServiceinterface. The ThreadPoolExecutor executes the given task (Callable or Runnable) using one of its internally pooled threads.
The thread pool contained inside the ThreadPoolExecutor can contain a varying amount of threads. 

The number of threads in the pool is determined by these variables:

corePoolSize, maximumPoolSize

If less than corePoolSize threads are created in the thread pool when a task is delegated to the thread pool, then a new thread is created, even if idle threads exist in the pool.

If the internal queue of tasks is full, and corePoolSize threads or more are running, but less than maximumPoolSize threads are running, then a new thread is created to execute the task.

Here is a diagram illustrating the ThreadPoolExecutor principles:




ScheduledExecutorService is an ExecutorServicewhich can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService

The main differences between a Lock and a synchronized block are:


· A synchronized block makes no guarantees about the sequence in which threads waiting to entering it are granted access.

·You cannot pass any parameters to the entry of a synchronized block. Thus, having a timeout trying to get access to a synchronized block is not possible.

·The synchronized block must be fully contained within a single method. A Lock can have it's calls to lock() and unlock() in separate methods.

Lock Methods

The Lock interface has the following primary methods:


·The lock() method locks the Lock instance if possible. If the Lock instance is already locked, the thread calling lock() is blocked until the Lock is unlocked.

·The lockInterruptibly() method locks the Lock unless the thread calling the method has been interrupted. Additionally, if a thread is blocked waiting to lock the Lock via this method, and it is interrupted, it exits this method calls.

·The tryLock() method attempts to lock the Lock instance immediately. It returns true if the locking succeeds, false if Lock is already locked. This method never blocks.

·The tryLock(long timeout, TimeUnit timeUnit) works like the tryLock() method, except it waits up the given timeout before giving up trying to lock the Lock.

·The unlock() method unlocks the Lock instance. Typically, a Lock implementation will only allow the thread that has locked the Lock to call this method. Other threads calling this method may result in an unchecked exception (RuntimeException).

Phasers

A phaser is a thread-synchronization construct that’s similar to a cyclic barrier in that it lets a group of threads wait on a barrier and then proceeds after the last thread arrives. It also offers the equivalent of a barrier action. However, a phaser is more flexible.
Unlike a cyclic barrier, which coordinates a fixed number of threads, a phaser can coordinate a variable number of threads, which can register at any time. To implement this capability, a phaser takes advantage of phases and phase numbers. A phase is the phaser's current state, and this state is identified by an integer-based phase number. When the last of the registered threads arrives at the phaser barrier, a phaser advances to the next phase and increments its phase number by 1.

Difference in Semaphore, mutex and lock
A lockallows only one thread to enter the part that's locked and the lock is not shared with any other processes.
A mutexis the same as a lock but it can be system wide.
A semaphoredoes the same as a mutex but allows x number of threads to enter.


What is the advantage of new Lock interface over synchronized block in Java?

The major advantage of lock interfaces on multi-threaded and concurrent programming is they provide two separate lock for reading and writing which enables you to write high performance data structure like ConcurrentHashMapand conditional blocking.



No comments:

Post a Comment