Sie sind auf Seite 1von 35

https://www.java-success.

com/

https://javarevisited.blogspot.com/

https://javahungry.blogspot.com/

https://dzone.com/articles/threads-top-80-interview

https://dzone.com/articles/top-80-thread-java-interview-0

https://codepumpkin.com/category/design-patterns/

1. How a thread can interrupt an another thread in Java?


2. isAlive() and join() methods of Thread Class in Java?
3. Asynchronous and Synchronous Callbacks in Java?
4. Deadlock and Starvation in Java?
5. Difference between Traditional Collections and Concurrent Collections in java?
6. Java.lang.InheritableThreadLocal Class with Examples?
7. Comparison of yield(), join() and sleep() in Java?
8. Runnable interface in Java?
9. Green vs Native Threads and Deprecated Methods in Java?
10. Builder Pattern in java?
11. Differences between wait() and join() methods in Java?
12. Difference Between Daemon Threads and User Threads In Java?
13. Killing threads in Java?
14. Thread Interference and Memory Consistency Errors in Java?
15. Difference between Thread.start() and Thread.run() in Java?
16. Difference between notify() and notifyAll() in Java?
17. Object level and Class level locks in Java?
18. Overloading of Thread class run() method?
19. Implement Runnable vs Extend Thread in Java?
20. Output of Java Programs | Set 46 (Multi-Threading) ?
21. Overriding of Thread class start() method?
22. Java.lang.ThreadGroup class in Java?
23. Java.lang.ThreadLocal class in Java?
24. Reentrant Lock in Java?
25. Thread Pools in Java?
26. Lifecycle and States of a Thread in Java?
27. CountDownLatch in Java ?
28. What does start() function do in multithreading in Java?
29. Inter-thread Communication in Java?
30. Synchronized in Java?
31. Difference between yield() ,sleep() and join()?
32. What is object lock and class lock ?
33. Is thread can acquire multiple lock simultaneously ?
34. what is synchronized block ?
35. Which method can release lock ?
36. In which class wait(),notify() method is defined?
37. Can we change Daemon thread nature of main thread?
38. What is green thread model?
39. You have thread T1, T2 and T3, how will you ensure that thread T2 run after T1 and
thread T3 run after T2?
40. What is the advantage of new Lock interface over synchronized block in Java? You need
to implement a high performance cache which allows multiple reader but single writer to
keep the integrity how will you implement it?
41. What is volatile keyword in Java? How to use it? How is it different from synchronized
method in Java?
42. What is race condition? How will you find and solve race condition?
43. How will you take thread dump in Java? How will you analyze Thread dump?
44. Why we call start() method which in turns calls run() method, why not we directly
call run() method ?
45. How will you awake a blocked thread in java?
46. What is difference between CyclicBarriar and CountdownLatch in Java ?
47. What are differences between wait and sleep method in java?
48. Write code to implement blocking queue in Java?
49. Write code to solve the Produce consumer problem in Java?
50. Write a program which will result in deadlock? How will you fix deadlock in Java?
51. What is atomic operation? What are atomic operations in Java?

1. Implementing Runnable over extending Thread(from composition over inheritance


perspective)
2. Synchronized collections vs concurrent collections(how they work/difference/when
should we chose one over other)
3. Lock interface and ReentrantLock, ReentrantReadWriteLock
4. Atleast three common synchronizers (Semaphore, CountDownlatch, CyclicBarrier)
usage/when to use one over another etc.
5. Synchronized context/Deadlock/Live Lock
6. Synchronized vs ReentrantLock
7. Thread pool, Executor Framework(at least fixed thread pool and cached thread pool),
ExecutionCompletionService when to use one over another, submit method and execute
method etc.
8. Callable/Runnable
9. Volatile variable and how it works during double checking case of Singletone
implementation
10. Thread Local
11. Thread life cycle methods ( atleast start/run/wait/notify/notifyall/sleep/yield)
12. race condition
13. Producer consumer problem
14. Interrupting a thread
15. Thread dump
16. Immutable objects

Some advanced Topics

———————————————

1. Stop a thread
2. Busy spin
3. Work steel algorithm and Fork Join framework
4. user thread/Demon Thread (like System.exit from both etc.)
5. Exception in Thread

Very advanced topics

——————————-

1. Java memory Model(happens before rule etc.)


2. The Disruptor Framework
3. What is multithreading?
4. Difference between process and thread in java?
5. What is thread in java?
6. What is the difference between preemptive scheduling and time slicing?
7. What is join method in java?
8. What is the difference between sleep and yield method?
9. Is it possible to start a thread twice in java?
10. Can we call run method directly in java?
11. What is daemon threads in java?
12. Can we make the user thread as daemon thread if thread is started?
13. Difference between thread start and run method.
14. Why we call start method in thread?
15. Which is a better way to create a thread in java?
16. Can we override start method?
17. Can we override run method?
18. How to get current thread in java?
19. What is synchronization?
20. What is synchronized block in java?
21. What is synchronized method in java?
22. What is static synchronization in java?
23. What is deadlock in java?
24. What is starvation in java?

Question 1. What are Threads in Java?

In Java, when a program requires more than one task to execute in parallel, say for example,
1. Reading a data from a local file.
2. Reading a data from remote connection.

When both of above task need to be executed in parallel at that time Threading will come in
picture.
So Java Threads helps creating multiple independent path of execution within a program which
can run parallely.

Question 2. How many ways Threads can be created in java?

There is only one way by which a Thread can be created in java using java.lang.Thread class as
shown below,
Thread thread1 = new Thread();

After creating a Thread object, a separate independent path is created but what task this
independent path will execute?
How many ways are there to assign task to a thread?
There are mainly 3 ways by which Task can be assigned to a Thread either by,

1. java.lang.Runnable
2. java.lang.Thread class itself.
3. java.util.concurrent.Callable Interface.

Let's see complete example of creating a Thread and assigning task to it using,

1. Runnable interface.
class ThreadDemo{
public static void main(String[] args) {

//Lets create Task first to assign it to the Thread


ThreadTask threadTask = new ThreadTask();

//Lets create a Thread and assign task to it.


//Way to assign task to a Thread is by passing task object(Runnable) to
Thread's constructor.
Thread thread1 = new Thread(threadTask);

//Start a thread
thread1.start();
}
}

class ThreadTask implements Runnable{


@Override
public void run() {
//Code present here will be executed in separate independent path.
}
}
2. Thread class
class ThreadDemo extends Thread{

@Override
public void run() {
//Code present here will be executed in separate independent path.
}

public static void main(String[] args) {

//Lets create Task first to assign it to the Thread


ThreadDemo threadTask = new ThreadDemo();

//Lets create a Thread and assign task to it.


//Way to assign task to a Thread is by passing task object(Runnable) to
Thread's constructor.
Thread thread1 = new Thread(threadTask);

//Start a thread
thread1.start();
}
}

3. Callable interface
class ThreadDemo{
public static void main(String[] args) {

//Create a Thread Pool of size 2 (2 here is number of threads in Thread


pool.)
ExecutorService executorService = Executors.newFixedThreadPool(2);
//After creating a pool, it internally starts a Thread, so no need to
explicitly start a thread as we did in other approach.
//Remember only Threads are started but what task they will execute that
will be passed to thread using submit() method.
//In this approach threads will be created and started but they will wait
for task to be assigned to them.

//Create Task to assign it to Threads present in Thread pool.


ThreadTask threadTask = new ThreadTask();

//Submit a task to Threads present in Thread pool.


Future<Result> resultObject = executorService.submit(threadTask);
//Once a task is submitted to submit method, one of the Thread from the
pool will pick the task and execute run method of task.
//Wait for the result Object(resultObject) that will be returned by Thread
after task execution.

Result result = null;


try {
//get method will be blocked until the Thread doesn't complete it work and
return a result
result = resultObject.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}

System.out.println(result.code + " " + result.message);


executorService.shutdown();
}
}
class ThreadTask implements Callable<Result> {

//method where the thread execution takes place


public Result call() {
//Code present here will be executed in separate independent path.
Result response = new Result();
response.code = 200;
response.message = "SUCCESS";
return response;
}

}
class Result{
public int code;
public String message;
}

So to summarize the answer, There is 1 way to create a Thread but task can be assigned to
Thread using 3 different ways either by using.

1. Runnable interface (run() method will be invoked)


2. Thread class (run() method will be invoked)
3. Callable interface (call() method will be invoked)
Question 3.
For starting a Thread we call thread.start() which internally invokes run()
method. What if we call run() method directly without using start() method ?

To answer this question one should know the purpose of start method and how Threading works
internally.

When a start() method is invoked, it internally invokes start0, which is a native method call.
private native void start0();
The basic purpose of start() method is to instruct running Operating System to create a new
Thread which can be executed independently of Thread created it.

when start() method is invoked, Thread will be created and it executes run() method of
Task submitted.

By calling thread.run() directly, will not create a new Thread instead it will call run method of
the task submitted on the same caller thread.
So there will be no separate execution for newly created Thread.

Question 4. Can we Start a thread twice ?

No. Thread cannot be started twice. If you try to do so, IllegalThreadStateException will be
thrown.
thread.start() can be called only once.
class ThreadDemo{
public static void main(String[] args) {

Thread thread1 = new Thread(new Runnable() {


public void run() {
System.out.println("Inside run.");
}
});
thread1.start();
thread1.start();
}
}

Output: Inside run. Exception in thread "main" java.lang.IllegalThreadStateException

How it throws IllegalThreadStateException?


If you see the code of start() method, you will observe that Thread maintains threadStatus
whose value initialy is 0 and once the thread is completed its value is 2.
private volatile int threadStatus = 0;
public synchronized void start() {

if (threadStatus != 0)
throw new IllegalThreadStateException();
}
....
....
}
So when thread.start() is called again, threadStatus value is 2 and not 0 that is why it throws
IllegalThreadStateException .

Question 5.
Can main thread dies before the child thread?
Does child threads still executes even after if their parent thread dies or
terminates?
Will JVM exits after main thread is dead?

First of all I would like to tell you that there is no concept of parent - child relationship between
threads.
Each and every thread created is independent of thread who created it.

Now coming back to actual question, Can main Thread dies before the child thread? Yes.
Main thread dies after completing its job even after the thread created by main thread is not yet
completed.
But point is will JVM die or not.
If there exist any non-daemon thread in JVM which is not yet completed then JVM will not
exit and wait until all no non-daemon threads completes its task.
In other words, we can also say, JVM will exit when the only running threads are daemon
threads.

Lets see example below and things will be more clear,


public class ThreadDemo {
public static void main(String ar[]){

final Thread mainThread = Thread.currentThread();


System.out.println("Inside Main Thread :"+mainThread.getName());

new Thread(new Runnable() {

@Override
public void run() {
Thread childThread= Thread.currentThread();
for(int i=0; i<5;i++){
System.out.println("Inside Child Thread :"+childThread.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Check Main Thread is alive :" +
mainThread.isAlive());
}

}).start();

System.out.println("End of Main Thread");


}
}

Question 6.
Is there any relationship between threads like parent-child?

No. Thre is no relationship between Threads like parent or child thread. Once thread is created it
is totaly separate independent thread from the thread who created it.

There is no relationship between Thread newly created and Thread who created it except for
Thread priority and Daemon property.

Thread priority and Daemon property of Thread is copied to the newly created thread from the
thread created it.
To put it in simple terms, When you start a thread it inherits the,

1. Thread daemon property and


2. Thread priority

from the "parent" thread to "child" thread and that is the only relationship between threads and
no other relation exist after thread starts.

Lets see with simple example,


public class ThreadDemo{

public static void main(String ar[]){


System.out.println("Inside Main Thread");

Thread thread = new Thread(new ThreadTask());


thread.setDaemon(true);
thread.start();

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End of Main Thread");
}
}
class ThreadTask implements Runnable{

@Override
public void run() {
System.out.println("Inside Thread Task start");

new Thread(new Runnable() {

public void run() {


Thread childThread = Thread.currentThread();
while(true){
System.out.println("Inside Child Thread :"+childThread.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}).start();

System.out.println("Inside Thread Task end");


}

}
Output:
Inside Main Thread
Inside Thread Task start
Inside Thread Task end
Inside Child Thread :Thread-1
Inside Child Thread :Thread-1
Inside Child Thread :Thread-1
Inside Child Thread :Thread-1
Inside Child Thread :Thread-1
End of Main Thread

After main thread completed, JVM terminates even if there was 2 threads present one was
Daemon thread and other thread inherited Daemon property from thread created it.

Question 7.
What is the use of join method in case of threading in java?

join() method is used for waiting the thread in execution until the thread on which join is called
is not completed.

Remember, the thread which will wait is the thread in execution and it will wait until the
thread on which join method called is not completed.

Lets take a scenario, we have Main thread, Thread 1, Thread 2 and Thread 3 and we want our
thread to execute in particular scenario like,
Main thread to start first and ends only after all 3 threads is completed.
Thread 1 to start and complete.
Thread 2 to start only after Thread 1 is completed.
Thread 3 to start only after Thread 2 is completed.

Let's see program for it.


public class ThreadDemo {
public static void main(String ar[]){
System.out.println("Inside Main Thread");

Thread thread1 = new Thread(new ThreadTask());


thread1.start();

Thread thread2 = new Thread(new ThreadTask(thread1));


thread2.start();

Thread thread3 = new Thread(new ThreadTask(thread2));


thread3.start();

try {
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End of Main Thread");
}
}
class ThreadTask implements Runnable{

public ThreadTask() {}

public ThreadTask(Thread threadToJoin) {


try {
threadToJoin.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public void run() {
System.out.println("Start Thread :"+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End Thread :"+Thread.currentThread().getName());
}
}

Output:
Inside Main Thread
Start Thread :Thread-0
End Thread :Thread-0
Start Thread :Thread-1
End Thread :Thread-1
Start Thread :Thread-2
End Thread :Thread-2
End of Main Thread
Question 8.
How join method works internally in java?

There is complete detailed post on this, Please go through it for answer.


Thread join() method works internally

Question 9.
When join method is invoked, does thread release its resources and goes in
waiting state or it keep resources and goes in waiting state?

If you look at source code of join() method, It internally invokes wait() method and wait()
method release all the resources before going to WAITING state.
public final synchronized void join(){
...
while (isAlive()) {
wait(0);
}
...
}
So, YES. join() method release resources and goes to waiting state.

Let's see sample program and understand,


class ThreadJoinDemo extends Thread{
static ThreadJoinDemo thread1;

public void run(){


try{
synchronized(thread1){
System.out.println(Thread.currentThread().getName()+" acquired a lock on
thread1");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+" completed");
}
}
catch (InterruptedException e){ }
}

public static void main(String[] ar) throws Exception{


thread1 = new ThreadJoinDemo();
thread1.setName("thread1");
thread1.start();

synchronized(thread1){
System.out.println(Thread.currentThread().getName()+" acquired a lock on
thread1");
Thread.sleep(1000);
thread1.join();
System.out.println(Thread.currentThread().getName()+" completed");
}
}
}

1. If you see the code, "main" thread took a lock on Thread "thread1" and waits for
thread1 to complete its task by calling thread1.join().
2. Thread "thread1", require a lock on "thread1" for executing its task.
If main thread doesn't release lock by calling thread1.join() then Thread "thread1" will
not able to progress and goes in deadlock state.

Question 10.
What is the practical use of join() method?

Suppose we want to calculate the population of country and based on population number further
action need to be taken.
we can break down this problem as calculating population of each state in a country.
What we can do is, if country has "n" states, we can create "n" threads(+1 main thread), each
calculating population of different states.
Now main thread can't do further action until all the state thread update population result.
So we can join all state threads on main thread, So that main thread will wait for all state thread
to complete and once result from all state thread is available it can make progress for further
actions.

Note: there can be many other ways to solve this problem.

Question 11.
Can Thread be created without any ThreadGroup, I mean can Thread exist
independently without associated to any ThreadGroup?

No. Thread cannot be created independently, it will be part of atleast one of the Thread Group.

Generally, while creating Thread we do not associate it to any Thread Group, but internally it
will be part of "main" Thread Group.

So let's see how ThreadGroup hierarchical structure is,


Threads / Thread Groups, which are directly created within main thread will be part of "main"
thread group and will be parallel to main thread.

What will be output of below lines?


public static void main(String[] args) {
System.out.println("Top Level Thread Group:" +
Thread.currentThread().getThreadGroup().getParent().getName());
System.out.println("Main Thread Group:" +
Thread.currentThread().getThreadGroup().getName());
}
Output:Top Level Thread Group: system
Main Thread Group: main

Question 12.
Say Thread "t1" is spawned from "main" thread, what happen when
RuntimeException is thrown from "t1", Will "main" thread continue to run?

Yes. "main" thread will continue to run if an exception is thrown from threads that are created
within main thread.

Let's see example and understand,


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

Thread t1 = new Thread(new Runnable() {


@Override
public void run() {
throw new RuntimeException("Thread Exception Example");
}
});
t1.start();
while(true){
System.out.println("ThreadDemo.main()");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

In above example, RuntimeException thrown by Thread "t1" will not affect "main" thread and it
continues to print "ThreadDemo.main()"

In general, Exception thrown by one thread will not affect another thread, as all threads are
independent and have different stack.

Question 13.
How exceptions are handled in case of Multithreading scenario? who will handle
Exceptions if there is no handler?

Exceptions that are thrown from Thread can be handled in 3 different ways,

1. At Thread Level
Each threads have there own Exception handling mechanism and can be caught and configured
in the way shown below,
Thread t1 = new Thread(new WorkerThread());
t1.setName("T4");

t1.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Thread Exception Handler :Thread Name :"+t.getName()
+ " Message :"+e.getMessage());
}
});
t1.start();

class WorkerThread extends Thread {


public void run() {
throw new RuntimeException("RuntimeException");
}
}
2. At ThreadGroup Level
Each ThreadGroup have there own Exception handling mechanism which will be applicable to
all thread within group and can be caught and configured in the way shown below,
ThreadGroup tr = new ThreadGroup("MyGroup"){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ThreadGroup Exception Handler :Thread Name
:"+t.getName() + " Message :"+e.getMessage());
}
};

Thread t1 = new Thread(tr, new WorkerThread());


t1.setName("T1");
t1.start();

2. At Global Thread Level


Default Exception Handler can be configured at Global thread level which will be applicable to
all the threads,
Thread.setDefaultUncaughtExceptionHandler(new
Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Default Exception Handler :Thread Name :"+t.getName() +
" Message :"+e.getMessage());
}
});

When an uncaught exception occurs from a particular Thread, the JVM looks for handler in way
shown below,

1. First JVM will look whether UncaughtExceptionHandler


(setUncaughtExceptionHandler) for the current Thread is set or not.

If set than exception will be catch by Thread handler.


If not set than exception will be propagated up the call stack.

2. Second JVM will check whether uncaughtException of ThreadGroup is overriden or


not,
JVM will not only check uncaughtException handler of direct ThreadGroup of which
Thread is part of, but JVM will also look at all the parent ThreadGroups as well.

If uncaughtException is overriden by any one of ThreadGroup handler than


exception will be caught by that ThreadGroup handler.
If not set than exception will be propagated up the call stack.

3. Third JVM will check whether DefaultUncaughtExceptionHandler


(setDefaultUncaughtExceptionHandler) at JVM level(Global Thread level) is configured
or not, It will act as handler for all the Threads in JVM.

If set than exception will be catch by Global Thread handler.


If not set than exception will be propagated up the call stack.
4. When there is no handler configured, Threadgroup class ("main" threadgroup to which
main thread is part of) provide default implementation of uncaughtException() method
that is called which prints Exception as shown below and JVM shutdowns.

System.err.print("Exception in thread \"" + t.getName() + "\" ");

Lets understand with help of example:

1. Global Exception handler for the application (JVM)


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

//Register Global Exception Handler for all Threads


Thread.setDefaultUncaughtExceptionHandler(new
Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Default Exception Handler :Thread Name :"+t.getName()
+ " Message :"+e.getMessage());
}
});

Thread t1 = new Thread(new Runnable() {


@Override
public void run() {
//Exception from New Thread spawned from "main" thread
throw new RuntimeException("I am RuntimeException");
}
});
t1.start();

while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

//Exception from main thread


throw new RuntimeException("I am RuntimeException");
}

}
}

Output:
Default Exception Handler :Thread Name :Thread-0 Message :I am
RuntimeException
Default Exception Handler :Thread Name :main Message :I am RuntimeException

2. ThreadGroup Exception handler for all Threads within ThreadGroup.


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

//Register ThreadGroup Exception Handler for all Threads that are part of
ThreadGroup.
ThreadGroup tr = new ThreadGroup("MyGroup"){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ThreadGroup Exception Handler :Thread Name
:"+t.getName() + " Message :"+e.getMessage());
}
};

Thread t1 = new Thread(tr, new Runnable() {


@Override
public void run() {
throw new RuntimeException("I am RuntimeException");
}
});
t1.setName("T1");
t1.start();

Thread t2 = new Thread(tr, new Runnable() {


@Override
public void run() {
throw new RuntimeException("I am RuntimeException");
}
});
t2.setName("T2");
t2.start();

}
}

Output:
ThreadGroup Exception Handler :Thread Name :T1 Message :I am RuntimeException
ThreadGroup Exception Handler :Thread Name :T2 Message :I am RuntimeException
3. Thread level Exception handler for particular Thread.
class ThreadDemo{
public static void main(String[] args) {

Thread t1 = new Thread(new Runnable() {


@Override
public void run() {
throw new RuntimeException("I am RuntimeException");
}
});

t1.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Thread Exception Handler :Thread Name :"+t.getName()
+ " Message :"+e.getMessage());
}
});
t1.start();
}
}

Output:
Thread Exception Handler :Thread Name :Thread-0 Message :I am
RuntimeException

Question 14.
If one Thread throws RuntimeException will complete application(other running
threads) goes down?

No. Only thread from which the exception is occured will terminate.
Other thread will continue to run and progress if an exception is thrown from one thread.

Let's see example and understand,


class ThreadDemo{
public static void main(String ar[]){

//Register Global Exception Handler for all Threads


Thread.setDefaultUncaughtExceptionHandler(new
Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Default Exception Handler :Thread Name :"+t.getName()
+ " Message :"+e.getMessage());
}
});

//Register ThreadGroup Exception Handler for all Threads in ThreadGroup


ThreadGroup tr = new ThreadGroup("MyGroup"){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ThreadGroup Exception Handler :Thread Name
:"+t.getName() + " Message :"+e.getMessage());
}
};

Thread t1 = new Thread(tr, new WorkerThread());


t1.setName("T1");
t1.start();

Thread t2 = new Thread(tr, new WorkerThread());


t2.setName("T2");
t2.start();

Thread t3 = new Thread(new WorkerThread());


t3.setName("T3");

t3.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e){
System.out.println("Thread Exception Handler :Thread Name :"+t.getName()
+ " Message :"+e.getMessage());
}
});
t3.start();

Thread t4 = new Thread(new WorkerThread());


t4.setName("T4");
t4.start();

Thread t5 = new Thread(new Runnable() {


@Override
public void run() {
while(true){
try {
System.out.println("I am printing");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t5.setName("T5");
t5.start();

}
}

In above example, RuntimeException thrown by Thread "t1", "t2", "t3", and "t4" will not affect
thread "t5" which prints "I am printing" and it continues to print even after exception is thrown
from other threads.

In general, Exception thrown by one thread will not affect another thread, as all threads are
independent and have different call stack. So exception from one thread will propagate up untill
the handler is not found and if no handler is configured then default "main" ThreadGroup handler
will be invoked for that particular thread.

Question 15.
How JVM handle Exceptions?

Have a look at below diagram and you will able to understand how JVM handles Exception ,
Question 16.
In case of Exception, What happen to lock which is acquired by Thread, will that
be released?

When an Exception is thrown from the Thread which hold lock on some resource say "obj",
Thread will release a lock on "obj", so that Thread in which Exception occured can be terminated
but other threads can still progress.

If say thread doesn't release lock on Exception, if this is the case then it may result in deadlock.
Say Thread "thread1" is waiting for lock on "obj" to enter in synchronized block.
Say Thread "thread2" is holding lock on "obj" and doing some operation and now if thread2
throws exception then "thread1" will be blocked and cannot progress.
If execution of the synchronized block completes normally, then the lock is unlocked and
the synchronized statement completes normally.

If execution of the synchronized block completes abruptly for any reason, then the lock is
unlocked and the exception is thrown until it finds exception handler up the call stack.
Question 17.
What is the output of the Program?
class ThreadDemo{
public static void main(String ar[]){
System.out.println(hello());
}

private static int hello(){


try{
throw new RuntimeException("dwed");
}finally{
return 10;
}
}
}
Output:
10

Why exception is not thrown?


When control entered hello() method, it encounters line in try block which throws
RuntimeException,
There is no handler for RuntimeException, so JVM will mark to throw exception up in call stack
and go for execution of finally block.

Finally block overwrote the JVM marked return statement to throw RuntimeException and now
return from finally block is result 10 and not RuntimeException.

Question 18.
Is it possible to take a lock on null reference? What is the output of the
Program?
class SynchronizationExample{
private static SynchronizationExample synchronizationExample = null;
public static void main(String ar[]){
hello();
}

private static void hello(){


synchronized (synchronizationExample) {
System.out.println("Inside synchronized block");
}
}
}
Output:
NullPointerException at line 8
Lock cannot be acquired on null reference.
calling a synchronized method on object and intrinsic acquiring a lock on that object is similar
to acquiring extrinsic lock by using synchronized() block.
public void synchronized method1(){}
calling obj1.method1() will hold a lock on obj1 (obj1 cannot be null otherwise NPE will be
thrown)
Similarly,
public void method1(){ synchronized(obj1){}}
obj1 at this point should also be not null for holding a lock on obj1.

When a method cannot be called on null reference and it throws NullPointerException if you try
to do so then how can you we acquire a lock on null refernce in synchronized block as both ways
of taking lock is similar.

Question 19.
When we cannot take a lock on null reference, what will happen if we make a
reference null after acquiring a lock on object it is referering to? What is the
output of the Program?
class SynchronizationExample{
private static SynchronizationExample synchronizationExample = new
SynchronizationExample();
public static void main(String ar[]){
hello();
}

private static void hello(){


synchronized (synchronizationExample) {
System.out.println("Before making reference null");
synchronizationExample = null;
System.out.println("After making reference null");
}
}
}
Output:
This is perfectly fine and outputs,
Before making reference null
After making reference null

Question 20.
What is the output of below program? Will synchronized block will be executed
in synchronized way as hello() method is executed on different object?
class SynchronizationExample{
private static Object obj = new Object();

public static void main(String ar[]){

new Thread(new Runnable() {


@Override
public void run() {
SynchronizationExample sy1 = new SynchronizationExample();
sy1.hello();
}
}).start();

new Thread(new Runnable() {


@Override
public void run() {
SynchronizationExample sy2 = new SynchronizationExample();
sy2.hello();
}
}).start();

private void hello(){


synchronized (obj) {
System.out.println("Thread :"+Thread.currentThread().getName() + "
Inside");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread :"+Thread.currentThread().getName() + "
Leaving");
}
}
}

Output:
Yes, It will be executed in synchronized way because sy1.hello() and sy2.hello() both
synchronize on the same STATIC object "obj" and hence execute in synchronized way.

Question 21.
synchronized block acquires locks on reference or object? Will call to method
hello1() and hello2() will exceute in synchronized way?
class SynchronizationExample{
private static final Object LOCK = new Object();
private Object lockReference1 = LOCK;
private Object lockReference2 = LOCK;
static SynchronizationExample se = new SynchronizationExample();

public static void main(String ar[]){


new Thread(new Runnable() {
@Override
public void run() {
se.hello1();
}
}).start();

new Thread(new Runnable() {


@Override
public void run() {
se.hello2();
}
}).start();

public void hello1() {


synchronized(lockReference1) {
System.out.println(Thread.currentThread().getName() + " in synchronized
block");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " leaving
synchronized block");

}
}

public void hello2() {


synchronized(lockReference2) {
System.out.println(Thread.currentThread().getName() + " in synchronized
block");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " leaving
synchronized block");
}
}

Output:
Yes, It will be executed in synchronized way because lockReference1 and lockReference2 both
pointing to same object (same memory location), So synchronized block acquires lock on object
and not the references that is why lock on null reference in synchronized block gives
NullPointerException.
Question 22.
For synchronizing and communicaion between threads, we use wait() and
notify() method inside synchronized method/block.
Threads acquire lock on common object and then calls wait() and notify() on
same object for their communication.

How to communicate between Threads which acquire class level lock.


wait() and notify() are not static and is instance method, so how to use for
communication between Threads which acquire class level lock?

There are 2 types of lock for each class,

1. object lock
2. Class lock

object lock:
Whenever a call to any instance method (getA()) is made using object obj1 in Thread t1, then t1
acquires lock on that object/instance (obj1).
public synchronized void getA(){}

Class lock
Whenever a call to any Class/static method (getD()) is made using class A in Thread t1, then t1
acquires lock on that Class (A).
public static synchronized void getD(){}

Both object and Class locks are different and they don't interfere with each other.

we can create multiple object's of a class and each object will have one lock associated with it.
When we acquire a lock on any class, we actually acquire a lock on "Class" class instance which
is only one for all instances of class.

For communication between Threads which acquire a lock on object, we call obj1.wait() and
obj1.notify().
For communication between Threads which acquire a lock on class A, we call A.class.wait() and
A.class.notify().

Let's understand it with example below,


class ThreadDemo{

public static void main(String[] args) {


final ThreadDemo threadDemo1 = new ThreadDemo();
new Thread(new Runnable() {
@Override
public void run() {
threadDemo1.getA();
}
}).start();

new Thread(new Runnable() {


@Override
public void run() {
threadDemo1.getB();
}
}).start();

new Thread(new Runnable() {


@Override
public void run() {
ThreadDemo.getC();
}
}).start();

new Thread(new Runnable() {


@Override
public void run() {
ThreadDemo.getD();
}
}).start();

/***INSTANCE METHOD***/
public synchronized void getA(){
System.out.println("ThreadDemo.getA() :"+Thread.currentThread().getName() +
" enetered");
try {
Thread.sleep(2000);
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadDemo.getA() :"+Thread.currentThread().getName() +
" leaving");
}

public synchronized void getB(){


System.out.println("ThreadDemo.getB() :"+Thread.currentThread().getName() +
" enetered");
try {
Thread.sleep(2000);
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadDemo.getB() :"+Thread.currentThread().getName() +
" leaving");
}
/***CLASS METHOD***/
public static synchronized void getC(){
System.out.println("ThreadDemo.getC() :"+Thread.currentThread().getName() +
" enetered");
try {
Thread.sleep(2000);
ThreadDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadDemo.getC() :"+Thread.currentThread().getName() +
" leaving");
}

public static synchronized void getD(){


System.out.println("ThreadDemo.getD() :"+Thread.currentThread().getName() +
" enetered");
try {
Thread.sleep(2000);
ThreadDemo.class.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadDemo.getD() :"+Thread.currentThread().getName() +
" leaving");
}

Proper communication happens with both instance lock and Class level lock.

Question 23.
Can thread switching happen while thread executing inside synchronized block?

Yes. Context switching can happen while in the synchronized block.

A synchronized block doesn't block other threads from executing and it only prevents
other threads from entering a block that is synchronized on the same object.
Other threads continue running while a synchronized block is being executed.

Context switching can happen while in the synchronized block, because other threads
should also get chance to progress
If context switching is not allowed while executing in synchronized block, then it is no longer
parallel execution and if code inside synchronized block requires much time to execute then it
will block everything else.
Question 24.
Non volatile variables that are updated inside synchronized block by Thread t1
(synchronized block of Thread t1 is not yet completed) is guaranteed to be visible
to Thread t2 and Thread t3 reading the same value?

If, Thread t1 changes value of "abc" variable.


Thread t2 may or may not read updated value of variable "abc".
Thread t3 is guaranteed to read updated value of variable "abc".

Let's take a example an understand,


class ThreadDemo {

private static final Object lock = new Object();


private String abc = "hello";

final AtomicInteger i = new AtomicInteger();

public void get1(){


synchronized(lock){
abc = "Hello :"+i.incrementAndGet();
//Consider at this point
//Thread t1 gets preempted and
//Thread t2 gets executed.
System.out.println("Changed :"+abc);
}
}
public void get2(){
System.out.println(abc);
}

public void get3(){


synchronized(lock){
System.out.println(abc);
}
}

public static void main(String args[]){


final StaticClass s = new StaticClass();

new Thread(new Runnable() {


public void run() {
s.get1();
}
}, "t1").start();

new Thread(new Runnable() {


public void run() {
s.get2();
}
}, "t2").start();

new Thread(new Runnable() {


public void run() {
s.get3();
}
}, "t3").start();

}
}

There are two type of memory barrier instructions in Java Memory Model,

1. read barrier.
2. write barrier.

Read Barrier
A read barrier invalidates the local memory (cache, registers, etc) and then reads the contents
directly from the main memory,
So that changes made by other threads becomes visible to the current Thread executing.

Write Barrier
A write barrier flushes out the contents of the processor's local memory to the main memory,
So that changes made by the current Thread becomes visible to the other threads.

When a thread acquires monitor(lock) on object, by entering into a synchronized block of code,
It first performs a Read Barrier (invalidates the local memory and reads from the heap instead).

Similarly exiting from a synchronized block as part of releasing the associated monitor,
It performs a Write Barrier (flushes changes to the main memory)

Case 1:
Modification of non-volatile variable in synchronized block by thread t1 is Guaranteed to be
visible to other thread t2 inside synchronized block only if it also acquires lock on same monitor.
public void get1(){
synchronized(lock){
abc = "Hello :"+i.incrementAndGet();
//Consider at this point Thread t1 gets preempted and Thread t2 gets
executed.
System.out.println("Changed :"+abc);
}
}

public void get3(){


synchronized(lock){
System.out.println(abc);
}
}

1. Thread t1 acquires lock on monitor "lock", reaches Read barrier, reads updated value of
variable
from memory.
2. Changes value of variable "abc" to "Hello..", writes the value to its local cache.
3. Thread t1 gets preempted and Thread t2 gets chance to execute and it calls a method get3().
4. Thread t2 acquires lock on same monitor "lock", reaches Read barrier, so all value updated
after
acquiring lock on monitor "lock" by other thread gets flushed to main memory before any
read
happens. updated value of variable "abc" that is "Hello.." by Thread t1 gets flushed to main
memory first.
5. So thread t2 reads updated value of variable "abc" inside synchronized block.

Case 2:
Modification of non-volatile variable in synchronized block by thread t1 is Not Guaranteed to
be visible to non synchronized thread t2.
public void get1(){
synchronized(lock){
abc = "Hello :"+i.incrementAndGet();
//Consider at this point Thread t1 gets preempted and Thread t2 gets
executed.
System.out.println("Changed :"+abc);
}
}

public void get2(){


System.out.println(abc);
}

1. Thread t1 acquires lock on monitor "lock", reaches Read barrier, reads updated value of
variable
from memory.
2. Changes value of variable "abc" to "Hello..", writes the value to its local cache.
3. Thread t1 gets preempted and Thread t2 gets chance to execute and it calls a method get2().
4. Thread t2 simply reads value of variable "abc" without any synchronization on same monitor,
So there is no read barrier and it is not guaranteed that partial update on variable "abc" by
thread t1
will be flushed to main memory and updated value may still be in thread cache
5. So thread t2 may gets updated value of variable "abc" or may not be as it is totally dependent
on
JVM whether it has sync thread t1 local memory to main memory or not yet.

Values are guaranteed to be updated only when read and write barrier happens, all intermediate
state of varaiables are not guaranteed to be flushed to main memory by JMM.

Question 25.
Why are local variables thread safe in Java?
Each thread will have its own stack which it uses to store local variables.
Two threads will have two stacks and one thread never shares its stack with other thread.

All local variables defined in method will be allocated memory in stack


As soon as method execution is completed by this thread, stack frame will be removed.

That means that local variables are never shared between threads.
//i is shared across threads
public class iIsNotThreadsafe {
int i = 0;
public int foo() {
i++;
return i;
}
}

//Each Thread will have local copy of i in its own call stack.
public class iIsThreadsafe {
public int foo() {
int i = 1;
i++;
return i+i;
}
}

43 Java Multithreading Interview Questions And Answers – Multithreading in Java


Interview Questions For Experienced 2018 from Codingcompiler. Test your Java
multithreading knowledge by answering these tricky interview questions on Java
Multithreading. Let’s start learning Java Multithreading interview questions and prepare for
Java interviews. All the best for your future and happy learning.

Java Multithreading Interview Questions

1. Define the concept of “process”.


2. Give the definition of “flow”.
3. Define the concept of “thread synchronization”.
4. How do programs, processes and threads interact?
5. When is it appropriate to create multiple streams?
6. What can happen if two threads execute the same code in the program?
7. What do you know about the main program flow?
8. What are the ways to create and run streams?
9. Which method starts a thread for execution?
10. What method describes the flow action at run time?
11. When does the thread finish its execution?
12. How to synchronize a method?
13. How to forcibly stop the flow?
14. Give the definition of the concept of “flow-demon”.
15. How to create a daemon thread?
16. How to get current stream?
17. Give the definition of “monitor”.
18. How to suspend the flow?
19. In what conditions can the flow be?
20. What is a monitor when calling a non-static and static method?
21. What is a monitor when executing a portion of a method code?
22. What methods allow you to synchronize the execution of threads?
23. What method puts a stream on standby?
24. What is the functionality of the notify and notifyAll methods?
25. What does the join method do?
26. What are the conditions for calling the wait / notify method?
27. Define the concept of “interlocking”.
28. What is the difference between interrupt, interrupted and isInterrupted methods?
29. In which case the InterruptedException will be thrown, what methods can throw it?
30. Modifiers volatile and the yield () method.
31. Package java.util.concurrent
32. There is some method that performs the operation i ++. The variable i is of type int. It is
assumed that the code will be executed in a multithreaded environment. Should I sync the
block?
33. What is used as a mutex if the method is declared static synchronized? Can I create new class
instances while the static synchronized method is running?
34. Suppose in the run method a RuntimeException occurred that was not caught. What happens to
the flow? Is there a way to know that an Exception has occurred (without enclosing the entire
run body in a try-catch block)? Is there a way to restore the thread after it happened?
35. What standard Java tools would you use to implement a thread pool?
36. What is a ThreadGroup and why is it needed?
37. What is a Thread Pool and why is it needed?
38. What is a ThreadPoolExecutor and why is it needed?
39. What is “atomic types” in Java?
40. Why do I need a class ThreadLocal?
41. What is Executor?
42. What is ExecutorService?
43. Why do I need ScheduledExecutorService?

Das könnte Ihnen auch gefallen