Sunday 2 April 2017

Multithreaing

Multithreding plays very important role in Java interviews. You can expect good number of questions on multithreading. 


1. How to create a thread in Java?

Answer: There are two ways we can create thread in Java:
1. By extending Thread class:  We can create thread directly by extending the java.lang.Thread class.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class ThreadExample {
 public static void main(String[] args) {
  MyThread myThread = new MyThread("My Thread");
  myThread.start();
 }
}

class MyThread extends Thread{
 public void run(){
  System.out.println("Thread Name::"+Thread.currentThread().getName());
 }
}

In MyThread class we overrided the run() method of java.lang.Thread to define what our thread will do. Purpose of run() method is to define the task for thread (in this case MyThread). Whatever we mention inside run() method will be executed by thread.
Then at line number 3 we created object of MyThread and made call to start() method. start() method is defined in java.lang.Thread class, which eventually calls your run() method. We are not supposed to call run() method directly.


Fig: Thread execution.

So till line number 5 there was only one thread executing and that was Main thread, but from line number 5 we got one more thread and that is My Thread. So both the thread will execute there task simultaneously, main thread will execute anything after line number 5 (if any, otherwise it will get terminated) and My Thread will execute it's own run() method.

2. By implementing Runnable interface: Second approach is by implementing the java.lang.Runnable interface.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class RunnableExample {
 public static void main(String[] args) {
  MyRunnable myRunnable = new MyRunnable();
  Thread myThread = new Thread(myRunnable);
  myThread.start();
 }
}

class MyRunnable implements Runnable{
 public void run(){
  System.out.println("Thread Name::"+Thread.currentThread().getName());
 }
}

For this approach everything will remain same as first approach except in this case we are using java.lang.Runnable interface.

Follow-up question 1: What is difference between above two approaches?

Answer: Main difference between these two approach is that when you opt for Runnable approach your class can sill extend other classes since Runnable is an interface. but in Thread class approach your class can not extend any other class since Java doesn't support multiple inheritance.
If you check implementation of  java.lang.Thread class, It itself implements Runnable interface. 

Follow-up question 2: Why we can not make call to run() method directly instead start() or what will happen if we call run() method directly instead of start()?

Answer: If we call run() method directly at line number 5, It will be a normal method call on myThread object. 
As start() method is responsible for creating a new thread and then calling run() method from that thread. If instead of calling start() method we call run() directly then there won't be a new thread and run() method will execute under current thread, It will be Main thread in above code.
But if we call start() of  java.lang.Thread method at line number 5It will create a new thread and then will execute run() method from that thread.
So we can conclude that start() method creates a new thread and then execute run() method inside that but if we make direct call to run() method, then it won't result in a  new thread instead it will use current thread.

2. Explain Thread life-cycle in Java?

AnswerLife cycle of thread in Java consist of following stages:
1. Created(New): When we create a new thread object, it goes into created(New) stage. Till this stage thread is just a normal Java object of Thread type.
2. Runnable: When you call start() method on thread object, it goes into Runnable stage. In this stage thread is ready to run but not actually running. In this stage thread wait for Thread Scheduler to pick it for execution. Here your normal Java object becomes a thread (execution branch).
3. Running: Once Thread Scheduler picks a thread for execution it goes into running stage. This is the stage where thread actually executes run() method.
4. Sleep/Waiting/Blocked: These stages are also know as non-running stages :
a. Sleep: When a thread call static method sleep(), It goes into sleep stage for a definite time period. Before going into sleep stage thread doesn't release the resources (locks on object) it has. Once sleep time period elapse thread again comes back to "runnable stage" .
b. Waiting: When a thread call non static method wait() on an object, It goes into waiting stage. Before going into waiting stage thread releases all the resources (lock on object) it has. Once any other thread calls notify() or notifyAll() method on same object waiting thread again comes back to "runnable stage".
c. Blocked: When a thread is waiting outside of synchronized block for other thread to complete it's task is called blocking stage. Once that other thread leaves synchronized block, blocking thread again comes back to "running stage".
5. Terminated: Once thread finished (completed run() method) it assigned task, it goes into terminated stage where thread dies.

Please refer below diagram for better understanding:
Fig: Thread Life Cycle.

3. Difference between sleep() and wait() method?

Answer: sleep() and wait() both the method send the thread into "waiting state" but there are following differences between these two:
1. sleep() is a static method and sends current thread into waiting stage for a definite amount of time and thread automatically comes out of waiting state once time elapse. But wait() is a non- static method defined in Object class which sends the thread into waiting stage where thread wait for a object(on which wait() called) to become free and thread can come back to runnable stage if either any thread calls notify() or noitifyAll() on same object or time elapsed if provided while calling wait().
2. The very important difference is "In sleep() method thread doesn't releases the locks it has before going into waiting stage. But in wait() method thread first releases the locks it has before going into waiting stage".
3. Usage wise sleep() method use for introducing pause in execution, whereas wait() method use for inter thread communication.


4.  Explain join() method?

Answerjoin() is non a static method defined in Thread class. Whenever a thread calls join method on another thread(s) then the caller thread has to wait for the thread(s)(on which join method called) to finish their task before get terminated.
So caller thread would terminate once the thread(s) on which join method called will finish their execution.
So caller thread terminates once all other thread(s) on which join method invoked terminate(join).
Example: If you run below code output will be:
main Started.
Thread Name::Thread-3
Thread Name::Thread-1
Thread Name::Thread-5
main Finished.
(Note: Thread finishing order can be different in your case)
Important thing is here that main thread started first and finished last because main thread has invoked join method on all the three threads. So main thread has to wait for all three thread to finish(or join) before terminated. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class ThreadJoinExample {
 public static void main(String[] args) {
  System.out.println(Thread.currentThread().getName() + " Started.");
  Thread thread1 = new Thread(new MyThread());
  Thread thread2 = new Thread(new MyThread());
  Thread thread3 = new Thread(new MyThread());
  
  thread1.start();
  thread2.start();
  thread3.start();
  
  try {
   thread1.join();
   thread2.join();
   thread3.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println(Thread.currentThread().getName() + " Finished.");
 }
}

class MyThread implements Runnable{

 @Override
 public void run() {
  System.out.println(Thread.currentThread().getName() + " Started.");
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //System.out.println(Thread.currentThread().getName() + " Finished.");
 }
 
}

If you comment the code from line 12 to 18 the output will be:
main Started.
main Finished.
Thread Name::Thread-3
Thread Name::Thread-1
Thread Name::Thread-5
(Note: again thread finished order can be different)
Here as you can see main thread started first and then it started all three child threads. After that main thread get terminated without waiting for other three threads to finish their task unlike in case of join() method.

5.  How to stop a thread in Java?

AnswerPlease find the code below: Here we have used shared variable(flag in this case "isStopped") which we will use to send single to thread whenever we want to stop.
As you can see in the code we are sending signal at line 8 by setting "isStopped" flag true after 5 second of sleep.
Also thread1 is running in a while loop where it keep checking for "isStopped" flag.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ThreadStop {

 public static void main(String[] args) throws InterruptedException {
  ThreadTask threadTask = new ThreadTask();
  Thread thread1 = new Thread(threadTask);
  thread1.start();
  Thread.sleep(5000);
  threadTask.setStopped(true);
 }

}


class ThreadTask implements Runnable{
 private volatile boolean isStopped = false;
 
 @Override
 public void run() {
  System.out.println(Thread.currentThread().getName() + " Started.");
  while(!isStopped){
   
  }
  System.out.println(Thread.currentThread().getName() + " Finished.");
 }

 public boolean isStopped() {
  return isStopped;
 }

 public void setStopped(boolean isStopped) {
  this.isStopped = isStopped;
 }
 
}
Note: There is an inbuilt stop() method defined in Thread class which we can directly use to kill thread but it is not recommended to use and it is deprecated by Oracle. Please find here official Oracle explanation for same.

No comments:

Post a Comment