1. What is Thread in java?
- Threads have their own stack.
- Multiple threads run parallely in java.
- Advantage of Thread : Suppose one thread needs 10 minutes to get certain task, 10 threads used at a time could complete that task in 1 minute, because threads can run parallely.
- Threads consumes CPU in best possible manner, hence enables multi processing. Multi threading reduces idle time of CPU which improves performance of application.
- Thread are light weight process.
- We can create multiple threads in java, even if we don’t create any Thread, one Thread at least do exist i.e. main thread.
2. What is difference between Process and Thread in java?
- One process can have multiple Threads,
- Thread are subdivision of Process. One or more Threads runs in the context of process. Threads can execute any part of process. And same part of process can be executed by multiple Threads.
- Processes have their own copy of the data segment of the parent process while Threads have direct access to the data segment of its process.
- Processes have their own address while Threads share the address space of the process that created it.
- Process creation needs whole lot of stuff to be done, we might need to copy whole parent process, but Thread can be easily created.
- Processes can easily communicate with child processes but interprocess communication is difficult. While, Threads can easily communicate with other threads of the same process using wait() and notify() methods.
- In process all threads share system resource like heap Memory etc. while Thread has its own stack.
- Any change made to process does not affect child processes, but any change made to thread can affect the behavior of the other threads of the process .
3. How to implement Threads in java?
Threads can be created in two ways i.e. by implementing java.lang.Runnable
interface or extending java.lang.Thread
class and then extending run method.
1. Thread creation by implementing java.lang.Runnable
interface.
Create Runnable object, pass it in thread constructor. But our thread is not going to start until we call thread.start()
, calling start()
method internally calls run()
method.
2. extending java.lang.Thread class
Thread creation by extending java.lang.Thread
class.
We will create object of class which extends Thread class :
MyThread obj=new MyThread();
But our thread is not going to start until we call obj.start()
calling start()
method calls run()
method.
If we note output of program, we will find that program started with main thread, and then calling obj.start() called run()
method with Thread-1
4. When to use Runnable vs Thread in Java?
1) Java doesn't support multiple inheritance, which means you can only extend one class in Java so once you extended Thread class you lost your chance and can not extend or inherit another class in Java.
2) In Object oriented programming extending a class generally means adding new functionality, modifying or improving behaviors. If we are not making any modification on Thread than use Runnable interface instead.
3) Runnable interface represent a Task which can be executed by either plain Thread or Executors or any other means. so logical separation of Task as Runnable than Thread is good design decision.
4) Separating task as Runnable means we can reuse the task and also has liberty to execute it from different means. since you can not restart a Thread once it completes. again Runnable vs Thread for task, Runnable is winner.
5) Java designer recognizes this and that's why Executors accept Runnable as Task and they have worker thread which executes those task.
6) Inheriting all Thread methods are additional overhead just for representing a Task which can can be done easily with Runnable.
5. What is the difference between start() and run() method of Thread class?
Main difference is that 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. Most of the time calling run()
is bug or programming mistake because caller has intention of calling start() to create new thread and this error can be detect by many static code coverage tools like findbugs. If you want to perform time consuming task than always call start()
method otherwise your main thread will stuck while performing time consuming task if you call run()
method directly. Another difference between start vs run in Java thread is that you can not call start()
method twice on thread object. once started, second call of start()
will throw IllegalStateException
in Java while you can call run()
method twice.
6. What is the difference between Runnable and Callable in Java?
1) The Runnable interface is older than Callable, there from JDK 1.0, while Callable is added on Java 5.0.
2) Runnable interface has run()
method to define task while Callable interface uses call()
method for task definition.
3) run()
method does not return any value, it's return type is void while call method returns value. The Callable interface is a generic parameterized interface and Type of value is provided when an instance of Callable implementation is created.
4) Another difference on run and call method is that run method can not throw checked exception while call method can throw checked exception in Java.
7. What is the difference between CyclicBarrier and CountDownLatch in Java?
CountDownLatch in Java is a kind of synchronizer which allows one Thread to wait for one or more Threads before starts processing. This is very crucial requirement and often needed in server side core Java application and having this functionality built-in as CountDownLatch greatly simplifies the development.
CyclicBarrier is similar to CountDownLatch the main difference between them is that you can not re-use CountDownLatch once count reaches to zero, but you can reuse same CyclicBarrier even after barrier is broken.
8. What is Java Memory model?
Java Memory model is set of rules and guidelines which allows Java programs to behave deterministically across multiple memory architecture, CPU, and operating system. It's particularly important in case of multi-threading. Java Memory Model provides some guarantee on which changes made by one thread should be visible to others, one of them is happens-before relationship. This relationship defines several rules which allows programmers to anticipate and reason behaviour of concurrent Java programs. For example, happens-before relationship guarantees :
Each action in a thread happens-before every action in that thread that comes later in the program order, this is known as program order rule.
An unlock on a monitor lock happens-before every subsequent lock on that same monitor lock, also known as Monitor lock rule.
A write to a volatile field happens-before every subsequent read of that same field, known as Volatile variable rule.
A call to Thread.start on a thread happens-before any other thread detects that thread has terminated, either by successfully return from Thread.join() or by Thread.isAlive() returning false, also known as Thread start rule.
A thread calling interrupt on another thread happens-before the interrupted thread detects the interrupt( either by having InterruptedException thrown, or invoking isInterrupted or interrupted), popularly known as Thread Interruption rule.
The end of a constructor for an object happens-before the start of the finalizer for that object, known as Finalizer rule.
If A happens-before B, and B happens-before C, then A happens-before C, which means happens-before guarantees Transitivity.
9. What is volatile variable in Java?
volatile is a special modifier, which can only be used with instance variables. In concurrent Java programs, changes made by multiple threads on instance variables is not visible to other in absence of any synchronizers e.g. synchronized keyword or locks. Volatile variable guarantees that a write will happen before any subsequent read
10. When to use Volatile variable in Java
1) Any variable which is shared between multiple threads should be made variable, in order to ensure that all thread must see the latest value of the volatile variable.
2) A signal to compiler and JIT to ensure that compiler does not change ordering or volatile variable and moves them out of synchronized context.
3) You want to save the cost of synchronization as volatile variables are less expensive than synchronization.
11. What is thread-safety? is Vector a thread-safe class?
Thread-safety is a property of an object or code which guarantees that if executed or used by multiple threads in any manner e.g. read vs write it will behave as expected. For example, a thread-safe counter object will not miss any count if same instance of that counter is shared among multiple threads. Apparently, you can also divide collection classes in two category, thread-safe and non-thread-safe. Vector is indeed a thread-safe class and it achieves thread-safety by synchronizing methods which modify state of Vector, on the other hand, its counterpart ArrayList is not thread-safe.
12. What is race condition in Java? Given one example?
Race conditions are just one of hazards or risk presented by use of multi-threading in Java just like deadlock in Java. Race conditions occurs when two thread operate on same object without proper synchronization and there operation interleaves on each other. Classical example of Race condition is incrementing a counter since increment is not an atomic operation and can be further divided into three steps like read, update and write. if two threads tries to increment count at same time and if they read same value because of interleaving of read operation of one thread to update operation of another thread, one count will be lost when one thread overwrite increment done by other thread. atomic operations are not subject to race conditions because those operation cannot be interleaved.
eg:
public Singleton getInstance(){ if(_instance == null){ //race condition if two threads sees _instance= null _instance = new Singleton(); } }
13. How to stop a thread in Java?
There was some control methods in JDK 1.0 e.g. stop(), suspend() and resume() which was deprecated in later releases due to potential deadlock threats, from then Java API designers has not made any effort to provide a consistent, thread-safe and elegant way to stop threads. Programmers mainly rely on the fact that thread stops automatically as soon as they finish execution of run() or call() method. To manually stop, programmers either take advantage of volatile boolean variable and check in every iteration if run method has loops or interrupt threads to abruptly cancel tasks.
14. What happens when an Exception occurs in a thread?
In simple words, If not caught thread will die, if an uncaught exception handler is registered then it will get a call back. Thread.UncaughtExceptionHandler is an interface, defined as nested interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception. When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler()
and will invoke the handler's uncaughtException() method, passing the thread and the exception as arguments.
15. 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 than item and do his 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, wondering why, read this link for some reasons which makes sense. Another important thing to keep in mind while calling them is, using loop to check conditions instead of if block.
Via Queue implementation it is able to do the data sharing between threads. See the example for more details
16. What is the difference between notify and notifyAll in Java?
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 and 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. So key difference between notify and notifyAll is that notify()
will cause only one thread to wake up while notifyAll method will make all thread to wake up.
17. Why wait, notify and notifyAll are not inside thread class?
1) Wait and notify is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don’t confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.
2 )Locks are made available on per Object basis, which is another reason wait and notify is declared in Object class rather then Thread class.
3) In Java in order to enter critical section of code, Threads needs lock and they wait for lock, they don't know which threads holds lock instead they just know the lock is hold by some thread and they should wait for lock instead of knowing which thread is inside the synchronized block and asking them to release lock. this analogy fits with wait and notify being on object class rather than thread in Java.
18. What is ThreadLocal variable in Java?
ThreadLocal in Java is another way to achieve thread-safety apart from writing immutable classes. If you have been writing multi-threaded or concurrent code in Java then you must be familiar with cost of synchronization or locking which can greatly affect Scalability of application, but there is no choice other than synchronize if you are sharing objects between multiple threads. 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. Since Object is no more shared there is no requirement of Synchronization which can improve scalability and performance of application.
19. When to use ThreadLocal in Java?
1) ThreadLocal are fantastic to implement Per Thread Singleton classes or per thread context information like transaction id.
2) You can wrap any non Thread Safe object in ThreadLocal and suddenly its uses becomes Thread-safe, as its only being used by Thread Safe. One of the classic example of ThreadLocal is sharing SimpleDateForamt. Since SimpleDateFormat is not thread safe, having a global formatter may not work but having per Thread formatter will certainly work.
3) ThreadLocal provides another way to extend Thread. If you want to preserve or carry information from one method call to another you can carry it by using ThreadLocal. This can provide immense flexibility as you don't need to modify any method.
Here is an example of ThreadLocal Variable
20. What is FutureTask in Java?
FutureTask represents a cancellable asynchronous computation in concurrent Java application. This class provides a base implementation of Future, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation. The result can only be retrieved when the computation has completed; the get methods will block if the computation has not yet completed. A FutureTask object can be used to wrap a Callable or Runnable object. Since FutureTask also implements Runnable, it can be submitted to an Executor for execution.
21. What is the difference between the interrupted()
and isInterrupted()
method in Java?
Main difference between interrupted()
and isInterrupted()
is that former clears the interrupt status while later does not. The interrupt mechanism in Java multi-threading is implemented using an internal flag known as the interrupt status. Interrupting a thread by calling Thread.interrupt()
sets this flag. When interrupted thread checks for an interrupt by invoking the static method Thread.interrupted()
, interrupt status is cleared. The non-static isInterrupted()
method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag. By convention, any method that exits by throwing an InterruptedException
clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt
22. Why wait and notify method are called from synchronized block?
we call wait ()
, notify ()
or notifyAll()
method in Java from synchronized method or synchronized block in Java to avoid:
- IllegalMonitorStateException in Java which will occur if we don't call wait (), notify () or notifyAll () method from synchronized context.
- Any potential race condition between wait and notify method in Java.
23. What is the difference between synchronized and concurrent collection in Java?
Though both synchronized and concurrent collection provides thread-safe collection suitable for multi-threaded and concurrent access, later is more scalable than former. Before Java 1.5, Java programmers only had synchronized collection which becomes source of contention if multiple thread access them concurrently, which hampers scalability of system. Java 5 introduced concurrent collections like ConcurrentHashMap, which not only provides thread-safety but also improves scalability by using modern techniques like lock stripping and partitioning internal table.
The synchronized collections classes, Hashtable and Vector, and the synchronized wrapper classes, Collections.synchronizedMap()
and Collections.synchronizedList()
, provides a basic conditionally thread-safe implementation of Map and List.
However, several factors make them unsuitable for use in highly concurrent applications, most importantly their single collection-wide lock is an impediment to scalability and it often becomes necessary to lock a collection for a considerable time during iteration to prevent ConcurrentModificationException.
The ConcurrentHashMap and CopyOnWriteArrayList implementations provide much higher concurrency and scalability while preserving the thread safety with some minor compromises in their promises to callers.
The ConcurrentHashMap and CopyOnWriteArrayList are not necessarily useful everywhere you might use HashMap or ArrayList, but are designed to optimize specific common situations. Many concurrent applications will benefit from their use.
So what is the difference between Hashtable and ConcurrentHashMap , both can be used in multi-threaded environment but once the size of Hashtable becomes considerable large performance degrade because for iteration it has to be locked for longer duration.
Since ConcurrentHashMap introduced concept of segmentation, It doesn't mater whether how large it becomes because only certain part of it get locked to provide thread safety so many other readers can still access map without waiting for iteration to complete.
24. What is the difference between Stack and Heap in Java?
1) The main difference between heap and stack is that stack memory is used to store local variables and function call while heap memory is used to store objects in Java. No matter, where the object is created in code e.g. as a member variable, local variable or class variable, they are always created inside heap space in Java.
2) Each Thread in Java has their own stack which can be specified using -Xss JVM parameter, similarly, you can also specify heap size of Java program using JVM option -Xms and -Xmx where -Xms is starting size of the heap and -Xmx is a maximum size of java heap. to learn more about JVM options see my post 10 JVM option Java programmer should know.
3) If there is no memory left in the stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError
, while if there is no more heap space for creating an object, JVM will throw java.lang.OutOfMemoryError
: Java Heap Space. Read more about how to deal with java.lang.OutOfMemoryError in my post 2 ways to solve OutOfMemoryError in Java.
4) If you are using Recursion, on which method calls itself, You can quickly fill up stack memory. Another difference between stack and heap is that size of stack memory is a lot lesser than the size of heap memory in Java.
Also note: Volatile fields are instance or class (static) variables and are stored in the heap.
5) Variables stored in stacks are only visible to the owner Thread while objects created in the heap are visible to all thread. In other words, stack memory is kind of private memory of Java Threads while heap memory is shared among all threads.
25. Write code to solve Producer Consumer problem in Java?
Producer Consumer problem is one of the classic multi-threading problems in computer science and the multi-threading world. It's tricky because it involves inter-thread communication, but it's important because most of the multi-threading problems fits into this category. There are many ways to solve producer consumer problem in Java e.g. you can solve this by using wait()
and notify()
method, you can use the Semaphore to solve this problem ...etc
The java.util.concurrent.BlockingQueue
is an interface and comes with two ready-made implementations then ArrayLinkedBlockingQueue
and LinkedBlockingQueue
. As the name suggests, one is backed by an array while other is backed by linked list
BlockingQueue provides a put()
method to store the element and take()
method to retrieve the element. Both are blocking method, which means put()
will block if the queue has reached its capacity and there is no place to add a new element. Similarly, take()
method will block if blocking queue is empty. So, you can see that critical requirement of the producer-consumer pattern is met right there, you don't need to put any thread synchronization code.
26. How to use Counting Semaphore in Concurrent Java Application?
java.util.Semaphore class represent a Counting semaphore which is initialized with number of permits. Semaphore provides two main method acquire() and release() for getting permits and releasing permits. acquire() method blocks until permit is available. Semaphore provides both blocking method as well as unblocking method to acquire permits.
27. How do you avoid deadlock in Java? Write Code?
Deadlock is a condition in which two threads wait for each other to take action which allows them to move further. It's a serious issue because when it happen your program hangs and doesn't do the task it is intended for. In order for deadlock to happen, following four conditions must be true:
- Mutual Exclusion : At least one resource must be held in a non-shareable mode. Only one process can use the resource at any given instant of time.
- Hold and Wait: A process is currently holding, at least, one resource and requesting additional resources which are being held by other processes.
- No Pre-emption: The operating system must not de-allocate resources once they have been allocated; they must be released by the holding process voluntarily.
- Circular Wait: A process must be waiting for a resource which is being held by another process, which in turn is waiting for the first process to release the resource.
The easiest way to avoid deadlock is to prevent Circular wait, and this can be done by acquiring locks in a particular order and releasing them in reverse order so that a thread can only proceed to acquire a lock if it held the other one.
Here is the fixed version, which avoids deadlock by avoiding circular wait with no preemption, one of the four conditions which need for deadlock.
28. What is the difference between livelock and deadlock in Java?
A livelock is similar to a deadlock, except that the states of the threads or processes involved in the livelock constantly change with regard to one another, without any one progressing further. Livelock is a special case of resource starvation. A real-world example of livelock occurs when two people meet in a narrow corridor, and each tries to be polite by moving aside to let the other pass, but they end up swaying from side to side without making any progress because they both repeatedly move the same way at the same time. In short, the main difference between livelock and deadlock is that in former state of process change but no progress is made.
29. How do you check if a Thread holds a lock or not?
There is a method called holdsLock()
on java.lang.Thread
, it returns true if and only if the current thread holds the monitor lock on the specified object.
30. How do you take thread dump in Java?
There are multiple ways to take thread dump of Java process depending upon operating system. When you take thread dump, JVM dumps state of all threads in log files or standard error console. In windows you can use Ctrl + Break key combination to take thread dump, on Linux you can use kill -3 command for same. You can also use a tool called jstack for taking thread dump, it operate on process id, which can be found using another tool called jps.
No comments:
Post a Comment