Concurrency Interview Questions

1. What is Thread in Java?

The thread is an independent path of execution. It’s way to take advantage of multiple CPU available in a machine. By employing multiple threads you can speed up CPU bound task.

For example, if one thread takes 100 milliseconds to do a job, you can use 10 thread to reduce that task into 10 milliseconds. Java provides excellent support for multi-threading at the language level, and it’s also one of the strong selling points.

2. Describe synchronization in respect to multi-threading. What is synchronization?

Several threads access common data.

In order to keep the data in consistent state the access to it has to be synchronized (i.e. some ordering of data access has to be imposed).

3. Explain different ways of using thread?

  1. Create a long-running computation in a separate thread so the user interface (or whatever other part of the application) is not blocked.
  2. separate out I/O operations which potentially can take a lot of time (e.g. reading from the network) for the same reason
  3. process incoming requests in parallel (usually using thread pool of some size)
  4. Create thread to do some kind of isolated processing, wait for the processing to finish, kill the thread. Create new threads when needed

4. How to stop a thread in Java?

I always said that Java provides rich APIs for everything but ironically Java doesn’t provide a sure shot way of stopping thread.

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.

 

5. What happens when an Exception occurs in a thread?

This is one of the good tricky Java question I have seen in interviews. 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.

6. How do you share data between two thread in Java?

You can share data between threads by using shared object, or concurrent data structure like BlockingQueue. It implements Producer consumer pattern using wait and notify methods, which involves sharing objects between two threads.

share-data-between-thread

7. What is the difference between preemptive scheduling and time slicing?

Not exactly a correct question.

A scheduler can be preemptive (it’s capable to force a process to interrupt its execution and resume it in some time) and non-preemptive (which is unable to interrupt a process and relies on the processes themselves that voluntarily give control to other tasks). Time slicing is a usual technique that is used in a preemptive multitasking system. The scheduler is run every time slice to choose the next process to run (it may happen that it’s the same process during few time slices in a row, or it may happen that every time slice a different process is executed )

To apply these terms to Java world – replace the “process” with “thread”, since the ideas behind scheduling processes in OS are the same as scheduling threads in an application.

8. When a thread is created and started, what is its initial state?

The thread is then in “RUNNABLE” state.

9. What is a thread local variable in Java?

Thread-local variables are variables confined to a thread, its like thread’s own copy which is not shared between multiple threads. Java provides a ThreadLocal class to support thread-local variables. It’s one of the many ways to achieve thread-safety.

Though be careful while using thread local variable in manged environment e.g. with web servers where worker thread out lives any application variable. Any thread local variable which is not removed once its work is done can potentially cause a memory leak in Java application.

ThreadLocal variables are special kind of variable available to Java programmer. Just like instance variable is per instance, ThreadLocal variable is per thread. It’s a nice way to achieve thread-safety of expensive-to-create objects, for example you can make SimpleDateFormat thread-safe using ThreadLocal.

Since that class is expensive, its not good to use it in local scope, which requires separate instance on each invocation. By providing each thread their own copy, you shoot two birds with one arrow.

First, you reduce number of instance of expensive object by reusing fixed number of instances, and Second, you achieve thread-safety without paying cost of synchronization or immutability.

Another good example of thread local variable is ThreadLocalRandom class, which reduces number of instances of expensive-to-create Random object in multi-threading environment.

 

10. When to use Runnable vs Thread in Java?

As we know we can implement thread either by extending Thread class or implementing Runnable interface, the question arise, which one is better and when to use one?

This question will be easy to answer if you know that Java programming language doesn’t support multiple inheritances of class, but it allows you to implement multiple interfaces. Which means, it’s better to implement Runnable then extends Thread if you also want to extend another class e.g. Canvas or CommandListener.

 

11. Thread vs Runnable, run() vs start()

The main difference between run() and start() is that the latter creates a separate thread while the former executes the code synchronously

One of trick Java question from early days, but still good enough to differentiate between shallow understanding of Java threading model start() method is used to start newly created thread, while start() internally calls run() method, there is difference calling run() method directly. When you invoke run() as normal method, its called in the same thread, no new thread is started, which is the case when you call start() method.

detail

12. Describe different ways to create a thread.

1. “`java class MyRunnable extends SomeOtherClass implements Runnable { public void run(){ // code that has to run in a thread } }

MyRunnable r = new MyRunnable(); Thread t = new Thread(r); r.start(); “`

2. “`java class MyThread extends Thread { public void run(){ // code that has to run in a thread } }

Thread t = new MyThred(); t.start(); 3. java class MySomething extends Something { public void doSomeStuff() {…} }

new Thread(new Runnable() { public void run(){ instanceOfMySomething.doSomeStuff(); } }).start(); “`

The main difference between these two approaches is that: * In case (1) you are able to extend the class you need while still being able to run your code in a separate thread. * In case (2) you are already extending from the Thread class which limits your options. In general following one of the good OOP practices (Favor composition over inheritance) option (a) is preferable. * Option (3) is also cute since it decouples your class and the fact that its code will be run in a separate thread. In other words you can still call instanceOfMySomething.doSomeStuff() regardless from a new thread or from the same.

Another answer is:

At the language level, there are two ways to implement Thread in Java. An instance of java.lang.Thread represent a thread but it needs a task to execute, which is an instance of interface java.lang.Runnable. Since Thread class itself implement Runnable, you can override run() method either by extending Thread class or just implementing Runnable interface.

 

13. Synchronization of Java blocks and methods

Methods declared synchronized and statements contained in synchronized blocks. Only one thread is allowed to be executing instructions inside a synchronized block.

The main difference between synchronized block and synchronized method is that you can choose which object will be used for synchronization in case of blocks. The methods are always synchronized with “this”

14. Explain usage of the couple wait()/notify()

The mechanism is used to allow one thread to signal another. E.g. Consumer signals that he’s waiting for the next object to process, or Producer signals that a new object is ready to be processed.

  • wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
  • notify() wakes up the a thread (a random one?) that called wait( ) on the same object.
  • notifyAll() wakes up all the threads that called wait( ) on the same object.

15. Why wait and notify method are called from synchronized block?

Main reason for calling wait and notify method from either synchronized block or method is that it made mandatory by Java API. 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.

 

16. What is the difference between notify and notifyAll in Java?

This is another tricky questions from core Java interviews. Since multiple threads can wait on single monitor lock, Java API designer provides method to inform only one of them or all of them, once waiting condition changes, but they provide half implementation.

There notify() method doesn’t provide any way to choose a particular thread, that’s why its only useful when you know that there is only one thread is waiting.

On the other hand, notifyAll() sends notification to all threads and allows them to compete for locks, which ensures that at-least one thread will proceed further.

17. Why wait, notify and notifyAll are not inside thread class?

This is a design related question, which checks what candidate thinks about existing system or does he ever thought of something which is so common but looks in-appropriate at first.

In order to answer this question, you have to give some reasons why it make sense for these three method to be in Object class, and why not on Thread class.

One reason which is obvious is that Java provides lock at object level not at thread level. 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. You can also see this article for more elaborate answer of this question.

 

18. How do you call wait() method? using if block or loop? Why?

wait() method should always be called in loop because it’s possible that until thread gets CPU to start running again the condition might not hold, so its always better to check condition in loop before proceeding. Here is the standard idiom of using wait and notify method in Java:

// The standard idiom for using the wait method
synchronized (obj) {
   while (condition does not hold)
      obj.wait(); // (Releases lock, and reacquires on wakeup)
      ... // Perform action appropriate to condition
}

19. What are differences between wait and sleep method in Java?

Though both are used to pause currently running thread.

  • sleep() is actually meant for short pause because it doesn’t release lock.
  • while wait() is meant for conditional wait and that’s why it release lock which can then be acquired by another thread to change the condition on which it is waiting.

20. What does Volatile keyword mean?

We typically use volatile keyword when we share variables with more than one thread in a multi-threaded environment, and we want to avoid any memory inconsistency errors due to the caching of these variables in the CPU cache.

The volatile keyword guarantees that reads and from a variable will see the changes made by the last write to this variable (and of course all other writes that happened earlier).

Java documentation states that volatile establishes a “happens-before” relationship between a write to a variable and all subsequent reads from it.

What is a Happens-before Relationship?

A happens-before relationship between two program statements is sort a guarantee which ensures that any memory writes by one statement are visible to another statement.

java-memory

When to use Volatile variable in Java?

  • Any variables which is shared between multiple threads should be made volatile, in order to ensure that all threads must see the latest value of volatile variable.
  • A signal to compiler and JIT to ensure that compiler does not change ordering or volatile variable and moves them out of synchronized context.
  • You want to save the cost of synchronization as volatile variables are less expensive than synchronization.
  • Another place where a volatile variable can be used is to fixing double checked locking in Singleton pattern

 

21. Difference between synchronized and volatile keyword in Java?

Remember volatile is not a replacement of synchronized keyword but can be used as an alternative in certain cases. Here are few differences between volatile and synchronized keyword in Java.

  1. The volatile keyword in Java is a field modifier while synchronized modifies code blocks and methods.
  2. Synchronized obtains and releases the lock on monitor’s Java volatile keyword doesn’t require that.
  3. Threads in Java can be blocked for waiting for any monitor in case of synchronized, that is not the case with the volatile keyword in Java.
  4. Synchronized method affects performance more than a volatile keyword in Java.
  5. Since volatile keyword in Java only synchronizes the value of one variable between Thread memory and “main” memory while synchronized synchronizes the value of all variable between thread memory and “main” memory and locks and releases a monitor to boot. Due to this reason synchronized keyword in Java is likely to have more overhead than volatile.
  6. You can not synchronize on the null object but your volatile variable in Java could be null.
  7. From Java 5 writing into a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire

22. The difference between Serializable and Externalizable in Java?

This is one of the frequently asked questions from Java Serialization. The interviewer has been asking this question since the day Serialization was introduced in Java, but yet only a few good candidate can answer this question with some confidence and practical knowledge.

Serializable interface is used to make Java classes serializable so that they can be transferred over network or their state can be saved on disk, but it leverages default serialization built-in JVM, which is expensive, fragile and not secure. Externalizable allows you to fully control the Serialization process, specify a custom binary format and add more security measure.

 

23. java.util.concurrent.* , what utils do you know?

  • Synchronization primitives: Semaphore, CyclicBarrier, CountDownLatch, Lock, ReentrantLock
  • Threads: Executors, Callable and Future
  • Data: Synchronized collections (CopyOnWriteArrayList, ConcurrentHashMap, BlockingQueue)

24. ThreadLocal, what for are they needed? Does child thread see the value of parent ThreadLocal?

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). The value need not be passed explicitly. It’s like how you use global variables.

One possible (and common) use is when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object. Instead, give each thread its own instance of the object. ThreadLocals are one sort of global variables (although slightly less evil because they are restricted to one thread), so you should be careful when using them to avoid unwanted side-effects and memory leaks. Design your APIs so that the ThreadLocal values will always be automatically cleared when they are not anymore needed and that incorrect use of the API won’t be possible (for example like this).

No. The child thread doesn’t see the value of parent ThreadLocal unless InheritableThreadLocal is used.

25. Recommendations to avoid deadlocks.

  1. We may create a class that will register all locks being held by all the threads. Thus before granting a new lock to a thread we may check whether it will not lead to a deadlock and grant the lock only if it doesn’t.
  2. We may devise a policy of acquiring the locks by the threads that will guarantee a deadlock-free program. A simple example of such policy is: no thread is allowed to have more than one lock at a time.

26. What is daemon thread and which method is used to create the daemon thread?

A daemon thread is a thread, that does not prevent the JVM from exiting when the program finishes but the thread is still running.

An example for a daemon thread is the garbage collection.

The setDaemon() method can be used to change the Thread daemon properties.

Normal thread and daemon threads differ in what happens when they exit. When the JVM halts any remaining daemon threads are abandoned: finally blocks are not executed, stacks are not unwound – JVM just exits. Due to this reason daemon threads should be used sparingly and it is dangerous to use them for tasks that might perform any sort of I/O.

27. What method must be implemented by all threads?

run(); by default (in the Thread class itself) it does nothing and returns

28. What is the difference between process and thread?

From Java documentation: A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space. Most implementations of the Java virtual machine run as a single process

Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads exist within a process – every process has at least one. Threads share the process’s resources, including memory and open files. This makes for efficient, but potentially problematic, communication.

Two process runs on different memory space, but all threads share same memory space.

Don’t confuse this with stack memory, which is different for the different thread and used to store local data to that thread.

29. What is an immutable object? How do you create an Immutable object in Java?

Immutable objects are those whose state cannot be changed once created.

Any modification will result in a new object e.g. String, Integer, and other wrapper class. Please see the answer for step by step guide to creating Immutable class in Java.

 

30. Can we create an Immutable object, which contains a mutable object?

Yes, its possible to create an Immutable object which may contain a mutable object, you just need to be a little bit careful not to share the reference of the mutable component, instead, you should return a copy of it if you have to. Most common example is an Object which contain the reference of java.util.Date object.

31. What are the states associated in the thread?

32. When you will synchronize a piece of your code?

Whenever there will be a need: most probably when there will be concurrent access to some data

33. What is deadlock? Example of deadlock.

Deadlock is a state in which some threads of an application (at least two threads) are mutually blocked (A waits for resource X held by B, while B waits for resource Y held by A). Neither can continue in this case. Note that only part of application can be in a deadlock state while other thread continue their execution.

public class DeadlockTest {
public static void main(String[] args) {

    String s1 = "S1";
    String s2 = "S2";

    Thread t1 = new Thread(new DeadlockCause(s1, s2));
    Thread t2 = new Thread(new DeadlockCause(s2, s1));

    t1.start();
    t2.start();

    }
}

class DeadlockCause implements Runnable {

    private final Object firstLock;
    private final Object secondLock;

    public DeadlockCause(Object o1, Object o2) {
        firstLock = o1;
        secondLock = o2;
    }

    @Override
    public void run() {
        synchronized(firstLock){
            System.out.println(Thread.currentThread().getName() +  " holds the lock on " + firstLock);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(DeadlockCause.class.getName()).log(Level.SEVERE, null, ex);
            }

            System.out.println(Thread.currentThread().getName() +  " tries to get the lock on " + secondLock);
            synchronized(secondLock){
                System.out.println(Thread.currentThread().getName() +  " holds the lock on " + secondLock);
            }
        }
    }
}

34. Are there any global variables in Java, which can be accessed by other part of your program?

No, there are no global variables in Java.

35. What are Callable and FutureTask interfaces?

Motivation to create: with Thread and Runnable you cannot return a value as the result of executing the task. Additionally you have to process all the exception inside the run() method because its declaration is public void run() and doesn’t allow exceptions to be thrown.

The Callable has the method public T call() throws Exception. When an ExecutorService gets submitted a Callable it returns a Future. The get() method on this Future instance has to be called in order to get the result.

Example:

 ExecutorService executor = Executors.newFixedThreadPool();
 Future<Integer> future = executor.submit(new Callable<Integer>(){
     public Integer call() throws Exception {
         Integer result = 0;
         // do some stuff here
         return result;
     }
 });

 executor.shutdown(); // stop accepting new tasks

 try {
     System.out.println("The result is: " + future.get());
 } catch (InterruptedException ex) {
     ...
 }

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.

36. 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.

37. What is the difference between Runnable and Callable in Java?

Both Runnable and Callable represent task which is intended to be executed in a separate thread.

Runnable is there from JDK 1.0 while Callable was added on JDK 1.5.

Main difference between these two is that Callable’s call() method can return value and throw Exception, which was not possible with Runnable’s run() method. Callable return Future object, which can hold the result of computation.

 

38. What is the difference between CyclicBarrier and CountDownLatch in Java?

Though both CyclicBarrier and CountDownLatch wait for number of threads on one or more events, 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

39. 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.

 

40. What is race condition in Java? Given one example?

Race condition are cause of some subtle programming bugs when Java programs are exposed to concurrent execution environment. As the name suggests, a race condition occurs due to race between multiple threads, if a thread which is supposed to execute first lost the race and executed second, behavior of code changes, which surface as non-deterministic bugs. This is one of the hardest bugs to find and re-produce because of random nature of racing between threads. One example of race condition is out-of-order processing, see this answer for some more example of race conditions in Java programs.

 

41. 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 behavior 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.

Advise: read chap 16 of “Java concurrency in practice”

42. What is Executors framework?

Oracle_JavaSE

43. What is AtomicInteger

AtomicInteger is a class from java.util.concurrent package that provides thread-safe implementation of an Integer.

More information on AtomicXXX can be found at Oracle_JavaSE

44. Why should you check condition for waiting in a loop?

Its possible for a waiting thread to receive false alerts and spurious wake up calls, if it doesn’t check the waiting condition in loop, it will simply exit even if condition is not met. As such, when a waiting thread wakes up, it cannot assume that the state it was waiting for is still valid. It may have been valid in the past, but the state may have been changed after the notify() method was called and before the waiting thread woke up. That’s why it always better to call wait() method from loop, you can even create template for calling wait and notify in Eclipse. To learn more about this question, I would recommend you to read Effective Java items on thread and synchronization.

 

45. 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.

 

46. What is the difference between Stack and Heap in Java?

Why does someone this question as part of multi-threading and concurrency? Because Stack is a memory area which is closely associated with threads.

To answer this question, both stack and heap are specific memories in Java application. Each thread has their own stack, which is used to store local variables, method parameters and call stack.

Variable stored in one Thread’s stack is not visible to other. On another hand, the heap is a common memory area which is shared by all threads.

Objects whether local or at any level is created inside heap. To improve performance thread tends to cache values from heap into their stack, which can create problems if that variable is modified by more than one thread, this is where volatile variables come into the picture. volatile suggest threads read the value of variable always from main memory.

stack_and_heap

 

47. What is thread pool? Why should you thread pool in Java?

Creating thread is expensive in terms of time and resource. If you create thread at time of request processing it will slow down your response time, also there is only a limited number of threads a process can create.

To avoid both of these issues, a pool of thread is created when application starts-up and threads are reused for request processing. This pool of thread is known as “thread pool” and threads are known as worker thread.

From JDK 1.5 release, Java API provides Executor framework, which allows you to create different types of thread pools e.g. single thread pool, which process one task at a time, fixed thread pool (a pool of fixed number of threads) or cached thread pool (an expandable thread pool suitable for applications with many short lived tasks).

 

48. Write code to solve Producer Consumer problem in Java?

Most of the threading problem you solved in the real world are of the category of Producer consumer pattern, where one thread is producing task and another thread is consuming that. You must know how to do inter thread communication to solve this problem.

49. How do you avoid deadlock in Java? Write Code?

deadlock

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. Check this tutorial for the actual code example and detailed discussion on techniques for avoiding deadlock in Java.

50. What is the difference between livelock and deadlock in Java?

This question is extension of previous interview question. 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.

51. How do you check if a Thread holds a lock or not?

I didn’t even know that you can check if a Thread already holds lock before this question hits me in a telephonic round of Java interview.

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.

 

52. 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.

 

53. Which JVM parameter is used to control stack size of a thread?

This is the simple one, -Xss parameter is used to control stack size of Thread in Java. You can see this list of JVM options to learn more about this parameter.

54. There are three threads T1, T2, and T3? How do you ensure sequence T1, T2, T3 in Java?

Sequencing in multi-threading can be achieved by different means but you can simply use the join() method of thread class to start a thread when another one has finished its execution. To ensure three threads execute you need to start the last one first e.g. T3 and then call join methods in reverse order e.g. T3 calls T2. join and T2 calls T1.join, these ways T1 will finish first and T3 will finish last.

55. What does yield method of Thread class do?

Yield method is one way to request current thread to relinquish CPU so that other thread can get a chance to execute. Yield is a static method and only guarantees that current thread will relinquish the CPU but doesn’t say anything about which other thread will get CPU. Its possible for the same thread to get CPU back and start its execution again.

56. What is Semaphore in Java?

Semaphore in Java is a new kind of synchronizer. It’s a counting semaphore.

Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it.

Each release() adds a permit, potentially releasing a blocking acquirer. However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.

Semaphore is used to protect an expensive resource which is available in fixed number e.g. database connection in the pool.

 

57. What happens if you submit a task when the queue of the thread pool is already filled?

This is another tricky question on my list. Many programmers will think that it will block until a task is cleared but its true. ThreadPoolExecutor’s submit() method throws RejectedExecutionException if the task cannot be scheduled for execution.

58. What is the difference between the volatile and atomic variable in Java?

This is an interesting question for Java programmer, at first, volatile and atomic variable look very similar, but they are different.

Volatile variable provides you happens-before guarantee that a write will happen before any subsequent write, it doesn’t guarantee atomicity. For example count++ operation will not become atomic just by declaring count variable as volatile.

On the other hand AtomicInteger class provides atomic method to perform such compound operation atomically e.g. getAndIncrement() is atomic replacement of increment operator. It can be used to atomically increment current value by one. Similarly you have atomic version for other data type and reference variable as well.

59. What happens if a thread throws an Exception inside synchronized block?

This is one more tricky question for average Java programmer, if he can bring the fact about whether lock is released or not is a key indicator of his understanding.

To answer this question, no matter how you exist synchronized block, either normally by finishing execution or abruptly by throwing exception, thread releases the lock it acquired while entering that synchronized block. This is actually one of the reasons I like synchronized block over lock interface, which requires explicit attention to release lock, generally this is achieved by releasing the lock in a finally block.

60. List down 3 multi-threading best practice you follow?

This is my favorite question because I believe that you must follow certain best practices while writing concurrent code which helps in performance, debugging and maintenance. Following are three best practices, I think an average Java programmer should follow:

  • Always give meaningful name to your thread This goes a long way to find a bug or trace an execution in concurrent code. OrderProcessor, QuoteProcessor or TradeProcessor is much better than Thread-1. Thread-2 and Thread-3. The name should say about task done by that thread. All major framework and even JDK follow this best practice.
  • Avoid locking or Reduce scope of Synchronization Locking is costly and context switching is even costlier. Try to avoid synchronization and locking as much as possible and at a bare minimum, you should reduce critical section. That’s why I prefer synchronized block over synchronized method because it gives you absolute control on the scope of locking.
  • Prefer Synchronizers over wait and notify Synchronizers like CountDownLatch, Semaphore, CyclicBarrier or Exchanger simplifies coding. It’s very difficult to implement complex control flow right using wait and notify. Secondly, these classes are written and maintained by best in business and there is good chance that they are optimized or replaced by better performance code in subsequent JDK releases. By using higher level synchronization utilities, you automatically get all these benefits.
  • Prefer Concurrent Collection over Synchronized Collection This is another simple best practice which is easy to follow but reap good benefits. Concurrent collection are more scalable than their synchronized counterpart, that’s why its better to use them while writing concurrent code. So next time if you need map, think about ConcurrentHashMap before thinking Hashtable. See my article Concurrent Collections in Java, to learn more about modern collection classes and how to make best use of them.

more

61. What is false sharing in the context of multi-threading?

false sharing is one of the well-known performance issues on multi-core systems, where each process has its local cache. false sharing occurs when threads on different processor modify variables that reside on same cache line as shown in the following image:

false-sharing

False sharing is very hard to detect because the thread may be accessing completely different global variables that happen to be relatively close together in memory. Like many concurrency issues, the primary way to avoid false sharing is careful code review and aligning your data structure with the size of a cache line.

detail

62. What is busy spin? Why should you use it?

Busy spin is one of the technique (waiting strategy) to wait for events without releasing CPU.

It’s often done to avoid losing data in CPU cached which is lost if the thread is paused and resumed in some other core.

So, if you are working on low latency system where your order processing thread currently doesn’t have any order, instead of sleeping or calling wait(), you can just loop and then again check the queue for new messages.

It’s only beneficial if you need to wait for a very small amount of time e.g. in micro seconds or nano seconds.

LMAX Disrupter framework, a high-performance inter-thread messaging library has a BusySpinWaitStrategy which is based on this concept and uses a busy spin loop for EventProcessors waiting on the barrier.

Leave a Reply

Your email address will not be published. Required fields are marked *