0% found this document useful (0 votes)
4 views62 pages

Multi Threading

The document provides a comprehensive overview of multithreading in Java, covering various ways to define threads, thread priorities, and methods to control thread execution. It discusses the differences between process-based and thread-based multitasking, as well as the advantages of implementing the Runnable interface over extending the Thread class. Additionally, it includes practical examples, thread lifecycle, synchronization, and common interview questions related to multithreading.

Uploaded by

stunning sathvik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views62 pages

Multi Threading

The document provides a comprehensive overview of multithreading in Java, covering various ways to define threads, thread priorities, and methods to control thread execution. It discusses the differences between process-based and thread-based multitasking, as well as the advantages of implementing the Runnable interface over extending the Thread class. Additionally, it includes practical examples, thread lifecycle, synchronization, and common interview questions related to multithreading.

Uploaded by

stunning sathvik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

Multithreading

Contents
1 Introduction ..................................................................................................................................................................... 2
2 Ways to define a Thread ................................................................................................................................................. 4
2.1 By Implementing Thread class ................................................................................................................................ 4
2.2 Thread Schedular..................................................................................................................................................... 4
2.3 By Implementing Runnable Interface. .................................................................................................................... 8
2.4 Which approach is best to define a Thread and why? ......................................................................................... 10
2.5 Thread class constructors...................................................................................................................................... 10
3 Getting and Setting name of a Thread. ......................................................................................................................... 11
4 Thread Priorities. ........................................................................................................................................................... 12
4.1 Default Priority ...................................................................................................................................................... 13
5 The Methods to prevent thread execution. ................................................................................................................. 15
5.1 yield() ..................................................................................................................................................................... 15
5.2 join()....................................................................................................................................................................... 16
5.2.1 What is the impact of join() on thread life cycle? ........................................................................................ 18
5.3 sleep() .................................................................................................................................................................... 20
5.3.1 How a Thread can interrupt another Thread? ............................................................................................. 21
6 Synchronization ............................................................................................................................................................. 23
6.1 lock ......................................................................................................................................................................... 24
6.2 Synchronized Block................................................................................................................................................ 37
7 Interview Questions ...................................................................................................................................................... 41
8 Inter Thread Communication ........................................................................................................................................ 42
8.1 wait(), notify() & notifyAll() .................................................................................................................................. 42
8.2 Producer Consumer Problem ................................................................................................................................ 48
8.3 Difference between notify() and notifyAll() ......................................................................................................... 49
9 Deadlock ........................................................................................................................................................................ 49
9.1 Deadlock vs Starvation .......................................................................................................................................... 52
10 Daemon Threads ....................................................................................................................................................... 52
10.1 Default nature of Thread ...................................................................................................................................... 52
11 Mutlithreading Models ............................................................................................................................................. 54
12 How to stop a Thread ................................................................................................................................................ 55
13 Mutlithreading Enhancement ................................................................................................................................... 57
13.1 Thread Groups ....................................................................................................................................................... 57
1 Introduction
1. Multitasking: -
a. Executing several tasks simultaneously is the concept of multitasking.
2. There are two types of Multitasking: -
a. Process Based Multitasking
b. Thread Based Multitasking
3. Process Based Multitasking: -
a. Executing several tasks simultaneously where each task is separate
independent program (process) is called Process based multitasking.
Example: -
While typing a java program into the editor, we can listen to music from the
same system and download a file from the Internet. All of these tasks will be
completed simultaneously and independently of one another. As a result,
process-based multitasking is best suited at the operating system level.
4. Thread Based Multitasking: -
a. Executing several tasks simultaneously where each task is a separate
independent part of same program.
b. Thread based multitasking is best suitable at programmatic level.
c. Whether it is process based or Thread based the main objective of
Multithreading is to reduce response time & improve performance of the
system.
d. The main important applications of Multithreading are: -
i. To develop Multimedia graphics.
ii. To develop Animation.
iii. To develop video games.

5. To develop web servers and application servers etc.

6. When compared with old languages developing multithreading application in Java is


very easy because java provides in-built support for multithreading with REACH API,
THREAD, RUNNABLE, THREADGROUP.
2 Ways to define a Thread
2.1 By Implementing Thread class

2.2 Thread Schedular


1. Case 1: -
a. It is the part of JVM, it is responsible to Schedule Threads i.e., If multiple threads
are waiting to get the chance of execution, then in which order threads are
executed is decided by Thread schedular.
b. We can’t expect exact algorithm followed by Thread Schedular it is varied from
JVM to JVM. Hence, we can’t expect threads execution order & exact output.
c. Whenever situation comes to multithreading there is no guarantee for exact
output but we can provide several possible outputs.
2. Case 2: -
a. Difference between t.start() & t.run() : -

b. In the case of t.start() method a new Thread will be created which is responsible
for the execution of run() method.
c. But in the case of t.run() method a new Thread will not be created & run() will be
executed just like a normal method call by Main Thread. Hence, in the above
program if we replace t.start() with t.run() then the output is “child thread 10
times followed by main thread 10 times this total output will be produced by
only main thread”.
3. Case 3: -
a. Importance of Thread class start(): -
i. Thread class start() is responsible to register the thread schedular and all
the mandatory activities hence without executing thread class start()
there is no chance of starting a new thread in Java. Due to this thread
class start() is considered as heart of Multithreading.
4. Case 4: -
a. It is always possible but thread class start() method can invoke no argument run()
other than overloaded method we have to call explicitly like a normal method call.
package com.MutliThreading;

class MyThread extends Thread {


@Override
public void run() {
System.out.println("No-arg run");
}

public void run(int i) {


System.out.println("int-arg run");
}
}

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
t.run(10);
}
}
Output: -
int-arg run
No-arg run
5. Case 5: -
a. If we are not overriding run() : -
i. Thread class run() will be executed which has empty implementation
hence we will not get any Output.

ii. Note: - It is highly recommended to override run() method otherwise


don’t go for multithreading concept.
6. Case 6: -
a. Overriding of start(): -
i. If we override start(), then our start() will be executed just like a normal
method & new thread will not be created.
package com.MutliThreading;
class MyThread extends Thread {
public void start() {
System.out.println("start method");
}

public void run() {


System.out.println("run method");
}
}

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
System.out.println("main method");
}
}
Output: -
start method
main method
ii. Note: - It is not recommended to override start(), otherwise don’t go for
multithreading concept.
7. Case 7: -

Output: -
8. Case 8: -
a. Thread life cycle: -

9. Case 9: -
a. After starting a thread, if we are trying to restart the same thread then we will get
runtime exception saying IllegalThreadStateException.

2.3 By Implementing Runnable Interface.

1. We can define a Thread by Implementing Runnable Interface.


2. Runnable Interface is present in java.lang package and it contains only one method
i.e., run() method.
public void run();

3. Case study: -
MyRunnable r = new MyRunnable();
Thread t1 = new Thread();
Thread t2 = new Thread(r);
a. Case 1: -
t.start();
i. A new Thread will be created and which is responsible for the creation of
Thread class run(), which has empty implementation.
b. Case 2: -
t.run();
i. No new Thread will be created Thread class run() will be executed just like
a normal call.
c. Case 3: -
t2.start();
i. A new Thread will be created which is responsible for the execution of
MyRunnable class run().
d. Case 4: -
t2.run();
i. A new Thread will not be created and MyRunnable run() will be executed
just like a normal method call.
e. Case 5: -
r.start();
i. We will get compile time error saying MyRunnable class does not have
start capability.
CE: Cannot find Symbol
Symbol: Method start()
Location class MyRunnable
f. Case 6: -
r.run();
i. No new Thread will be created and runnable run() will be executed like
normal method call.
2.4 Which approach is best to define a Thread and why?
1. In the first approach our class always extends Thread class, there is no chance of
extending other class. Hence, we are missing Inheritance benefit.
2. But, in the second approach while implementing Runnable Interface we can extend
any other class. Hence, will not miss any Inheritance benefit because of above
reason, implementing Runnable interface is recommended than extending Thread
class.
2.5 Thread class constructors
1. Thread t = new Thread();
2. Thread t = new Thread(Runnable r);
3. Thread t = new Thread(String name);
4. Thread t = new Thread(Runnable r, String name);
5. Thread t = new Thread(ThreadGroup g, String name);
6. Thread t = new Thread(ThreadGroup g, Runnable r);
7. Thread t = new Thread(ThreadGroup g, Runnable r, String name);
8. Thread t = new Thread(ThreadGroup g, Runnable r, String name, long stacksize);
package com.MutliThreading;

class MyThread extends Thread {


@Override
public void run() {
System.out.println("Child Thread");
}
}

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
t1.start();
System.out.println("Main Thread");
}
}
Output 1: -
Main Thread
Child Thread
Output 2: -
Child Thread
Main Thread
Above approach is not recommended to use.

3 Getting and Setting name of a Thread.


package com.MutliThreading;

class MyThread7 extends Thread {

}
public class ThreadDemo6 {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
//Output --> main
MyThread7 t = new MyThread7();
System.out.println(t.getName());
//Output --> Thread - 0
Thread.currentThread().setName("Pawan Kalyan");
System.out.println(Thread.currentThread().getName());
//Output --> Pawan Kalyan
System.out.println(10/0);
/* Exception in thread "Pawan Kalyan"
java.lang.ArithmeticException: / by zero
at com.MutliThreading.ThreadDemo6.main(ThreadDemo6.java:16)
*/
}
}
Output: -
main
Thread-0
Pawan Kalyan
Exception in thread "Pawan Kalyan" java.lang.ArithmeticException: / by zero
at com.MutliThreading.ThreadDemo6.main(ThreadDemo6.java:16)
1. Every Thread in java has some name it may be default name generated by JVM or
customized provided by programmer.
2. We can get and set name by using Thread class methods.
a. public final String getName();
b. public final void setName();
package com.MutliThreading;

class MyThread8 extends Thread {


@Override
public void run() {
System.out.println("This line executed by Thread " +
Thread.currentThread().getName());
}
}

public class ThreadDemo7 {


public static void main(String[] args) {
MyThread8 t = new MyThread8();
t.start();
System.out.println("This line executed by Thread " +
Thread.currentThread().getName());
}
}
Output: -
This line executed by Thread main
This line executed by Thread Thread-0
3. Note: - Current Thread Executing object by using Thread.currentThread();

4 Thread Priorities.
1. Every Thread in java has some priority, it may be default priority generated by JVM or
Customized priority provided by programmer.
2. The valid range of Thread priority is 1 to 10, where 1 is the Minimum priority & 10 is
Maximum priority.
3. Thread class defines the following constants to represent some standard priorities.
a. Thread.MIN_PRIORITY → 1
b. Thread.NORM_PRIORITY → 5
c. Thread.MAX_PRIORITY → 10

4. Thread schedular will use priorities while allocating processor.


5. The Thread which is having highest priority will get the chance first.
6. If two Threads having same priority then we cannot expect exact execution order, it
depends on Thread schedular.
7. Thread class defines the following methods to get & set priorities of Threads.

4.1 Default Priority


1. The Default priority only for the main Thread is 5.
2. All remaining Threads Default priority will be Inherited from parent to child. i.e.,
Whatever priority thread has the same priority will be there for the child thread.
package com.MutliThreading;

class MyThread9 extends Thread {

public class ThreadDemo8 {


public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority()); // 5
// Thread.currentThread().setPriority(15);
// RE: IllegalArgumentException
Thread.currentThread().setPriority(7); // Line - 1
MyThread9 t = new MyThread9();
System.out.println(t.getPriority()); // 7
// If we comment line 1 then child thread priority will become 5
}
}
Output: -
5
7

package com.MutliThreading;
class MyThread10 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child thread");
}
}
}
public class ThreadDemo9 extends Thread {
public static void main(String[] args) {
ThreadDemo9 t = new ThreadDemo9();
t.setPriority(10); // Line - 1
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main thread");
}
}
}
Output: -
Main thread
Main thread
Main thread
Main thread
Main thread
Main thread
Main thread
Main thread
Main thread
Main thread
Child thread
Child thread
Child thread
Child thread
Child thread
Child thread
Child thread
Child thread
Child thread
Child thread
3. If we are commenting Line 1 then both main and child threads have the same priority
5 and hence, we cannot expect execution order and exact output.
4. If we are not commenting Line 1 then main thread has the priority 5 and child has the
priority 10.
5. Hence, Child Thread will get the chance first followed by Main Thread.
Child thread
Child thread 10 times
Followed by main thread
main thread 10 times
Some platform will not provide proper support for thread priorities.

5 The Methods to prevent thread execution.


1. We can prevent a thread execution by using following methods.
a. yield()
b. join()
c. sleep()
5.1 yield()

1. The yield() method causes the current executing thread to pause in order to give the
opportunity to a waiting thread with the same priorities.
2. If there are no waiting threads or all waiting threads have no priorities then same
thread can continue its execution.
3. If multiple threads are waiting with same priority, then we cannot expect and its
execution order depends on Thread schedular.

4. The Thread which is yielded (means left the processor), it will get the chance once
again and it depends on Thread schedular and we can’t expect exactly.
public static native void yield();
5. Thread Life cycle: -

6. Thread.yield() → Causes to pause current executing thread to give the chance for
remaining threads of same priority for that purpose we can use yield() method.
package com.MutliThreading;

class MyThread11 extends Thread {


public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("Child Thread");
Thread.yield(); // Line 1
}
}
}

public class ThreadYieldDemo {


public static void main(String[] args) {
MyThread11 t = new MyThread11();
t.start();
//----->
for(int i = 0; i < 10; i++) {
System.out.println("Main Thread");
}
}
}
7. In the above program, if we are commenting Line 1 then both Thread will be
executed simultaneously and we cannot expect which Thread will complete first.
8. If we are not commenting Line 1 then Child Thread always calls yield method because
of that Main Thread will get a greater number of chances and the chance of Main
Thread completing first is High.
9. Note: - Some platforms don’t provide support for yield() method.
5.2 join()
1. If a Thread wants to wait until completing some other Threads then we should go for
join() method.
2. For Example,
If a Thread t1 wants to wait until completing t2 then t1 has to call t2.join().

3. If t1 executes t2.join() then immediately t1 will be entered into waiting state until t2
completes. Once t2 completes then t1 can complete its execution.

4. Wedding card printing thread t2 has to wait until venue fixing thread t1 completion.
Hence, t2 has to call join method. Wedding card distribution thread t3 has to wait
until Wedding card printing thread t2 completion. Hence, t3 has to call t2.join()
method.
5. There are 3 join methods: -
public final void join(); throws InterruptedException
public final void join(long ms); throws InterruptedException
public final void join(long ms, int ns); throws InterruptedException
6. Note: - Every join method throws InterruptedException which is checked Exception.
Hence, compulsory we should handle this Exception either by using try-catch or
throws keyword otherwise we will get Compile time Error.
7. Thread life cycle: -

5.2.1 What is the impact of join() on thread life cycle?


1. If Thread Schedular allocates processor then thread will come into running state.
2. Case 1: - Waiting of Main Thread until Completion of Child Thread.
package com.MutliThreading;
// Case 1 --> Waiting of Main Thread until completing child thread
class MyThread12 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Rashmika Thread");
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {

}
}
}

public class ThreadJoinDemo {


public static void main(String[] args) throws InterruptedException {
MyThread12 t = new MyThread12();
t.start();
// t.join(); Line 1
for (int i = 0; i < 10; i++) {
System.out.println("Ballaya Thread");
}
}
}
a. If we comment Line 1 then both main and child threads will be executed
simultaneously and we cannot expect exact output.
b. If we are not commenting Line 1 then main thread calls join method on child
thread object. Hence, main thread will wait until completing child thread in this
case output is:
Rashmika thread
Rashmika thread 10 times
Followed by Ballaya thread
Ballaya thread 10 times
3. Case 2: - Waiting of child thread until completing main thread.
package com.MutliThreading;

class MyThread13 extends Thread {


static Thread mt;
@Override
public void run() {
try {
mt.join();
} catch (InterruptedException e) {}
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
}
}
}

public class ThreadJoinDemo1 {


public static void main(String[] args) throws InterruptedException {
MyThread13.mt = Thread.currentThread();
MyThread13 t = new MyThread13();
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main Thread");
Thread.sleep(2000);
}
}
}
a. In the above example, Child Thread calls join method on Main Thread object.
Hence, Child Thread has to wait until completion of Main Thread.
4. Case 4: -
a. If Main Thread calls join method on Child Thread object & Child Thread calls join
method on Main Thread object then both threads will wait forever and the
program will be stuck this will be something like deadlock.
package com.MutliThreading;

class MyThread13 extends Thread {


static Thread mt;
@Override
public void run() {
try {
mt.join();
} catch (InterruptedException e) {}
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
}
}
}

public class ThreadJoinDemo1 {


public static void main(String[] args) throws
InterruptedException {
MyThread13.mt = Thread.currentThread();
MyThread13 t = new MyThread13();
t.start();
t.join();
for (int i = 0; i < 10; i++) {
System.out.println("Main Thread");
Thread.sleep(2000);
}
}
}
5. Case 5: -
a. If a Thread call join method on same thread, then the program will be stuck this is
something like Deadlock.
b. In this case, the Thread has to wait Initiate amount of time.
package com.MutliThreading;

public class ThreadJoinDemo2 {


public static void main(String[] args) throws
InterruptedException {
Thread.currentThread().join();
// main thread --> Executed by main thread
}
}
5.3 sleep()
1. If a Thread don’t want to perform any execution for a particular amount of time, then
we should go for sleep().
2. There are two sleep methods: -
a. public static native void sleep(long ms) throws InterruptedException
b. public static native void sleep(long ms, int ns) throws InterruptedException
3. Note: - Every sleep method throws InterruptedException which is checked Exception.
Hence, whenever we are using sleep() method compulsory we should handle
InterruptedException either by try-catch or throws keyword. Otherwise, we will get
Compile time Error.
4. Thread Life Cycle: -

package com.MutliThreading;

public class SlideRotator {


public static void main(String[] args) throws InterruptedException{
for (int i = 1; i <= 10; i++) {
System.out.println("slide-"+i);
Thread.sleep(5000);
}
}
}
Output: -
slide-1
slide-2
slide-3
slide-4
slide-5
slide-6
slide-7
slide-8
slide-9
slide-10
5.3.1 How a Thread can interrupt another Thread?
1. A Thread can interrupt a sleeping Thread or waiting Thread by using interrupt()
method of a Thread class.
public void interrupt().
package com.MutliThreading;

class MyThread14 extends Thread {


@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("I am a Lazy Thread");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("I got Interrupted");
}
}
}

public class ThreadSleepDemo {


public static void main(String[] args) {
MyThread14 t = new MyThread14();
t.start();
// t.interrupt(); Line 1
System.out.println("End of main Thread");
}
}
2. If we comment Line 1 then main Thread will not Interrupt child Thread in this case
child Thread will execute for loop 10 times.
3. If we don’t comment line 1 then main Thread interrupt child Thread in this case
output is:
End of main Thread
I am a Lazy Thread
I got Interrupted
4. Whenever, we are calling interrupt() method if the target thread is not in sleeping or
waiting state then there is no impact of interrupt call immediately interrupt call be
waited until target Thread entered into sleeping state or waiting state.
5. If the target Thread entered into sleeping or waiting state then immediately interrupt
call will interrupt target Thread.
6. If the target Thread never entered into sleeping or waiting state in its life time then
there is no impact of interrupt call this is the only case where interrupt call will be
wasted.
package com.MutliThreading;

class MyThread15 extends Thread {


@Override
public void run() {
for (int i = 0; i <= 10000; i++) {
System.out.println("I am a Lazy Thread- " + i);
}
System.out.println("I am entering into sleeping mode");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("I got interrupted");
}
}
}

public class ThreadSleepDemo1 {


public static void main(String[] args) {
MyThread15 t = new MyThread15();
t.start();
t.interrupt();
System.out.println("End of main Thread");
}
}
7. In the above example, Interrupted call waited until child Thread completes for loop
10,000 times.
Property yield() join() sleep()
Purpose If a Thread wants If a Thread If a Thread does not
to pause its wants to wait want to perform any
execution to give until operation for a
the chance for completing particular amount of
remaining threads some other time, then we go for
of same priority. Threads, then sleep method.
we should go
for Join
method.
Is it overloaded No Yes Yes
Is it final No Yes No
Is it throws No Yes Yes
InterruptedException
Is it native Yes No sleep(long ms) → Yes
sleep(long ms, int ns)
→ No
Is it static Yes No Yes

6 Synchronization

1. The synchronized modifier is only applicable to methods and blocks, not classes and
variables.
2. If multiple Threads attempt to operate on the same Java object at the same time, there
is a risk of data inconsistency. To avoid this, we should use the synchronized keyword.
3. If a method or block is declared as synchronized, only one Thread may execute that
method or block at a time. As a result, the issue of data inconsistency will be resolved.
4. The main advantage of the synchronized keyword is that it allows us to resolve data
inconsistency issues, but the main disadvantage is that it increases the waiting time of
Threads and causes performance issues. As a result, if there is no specific requirement,
the synchronized keyword is not recommended.
6.1 lock
1. Lock is used internally to implement the synchronization concept. Every object in Java
has a unique lock, and when we use the synchronized keyword, only the lock concept
comes into play.
2. If a Thread wants to execute a synchronized method on a given object, it must first
obtain Lock on that object. Once Thread has obtained the Lock, it is free to execute any
synchronized method on that object.
3. Thread will automatically release the Lock once method execution is complete. Internal
acquisition and release are handled by the JVM, and the programmer is not responsible
for this activity.

4. While a Thread is executing a synchronized method on a given object, the remaining


Threads are not permitted to execute any synchronized method on the same object at
the same time, but they are permitted to execute non-synchronized methods
concurrently.
5. The lock concept is implemented on the basis of an object rather than a method.
6. Below program illustrates how a single thread executes a task without interference from
other threads.
package com.MutliThreading;

class Display {
public void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d = new Display();
MyThread1 t1 = new MyThread1(d, "Dhoni");
t1.start();
}
}
Output
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
7. Below example illustrates the concept of unsynchronized thread execution and the
resulting irregular output.
package com.MutliThreading;

class Display {
public void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
Display d2 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d2, "Yuvraj");
t1.start();
t2.start();
}
}
Output:
Good Morning: Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Yuvraj

8. Below program showcases how unsynchronized methods can lead to thread


interference, resulting in unpredictable output.
package com.MutliThreading;

class Display {
public void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}
@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d1, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning: Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Yuvraj
Good Morning: Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Dhoni
9. Below program demonstrates the chaotic output and unpredictable behavior that result
from multiple threads accessing the same object without synchronization.
package com.MutliThreading;

class Display {
public void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d1, "Yuvraj");
MyThread1 t3 = new MyThread1(d1, "Raina");
MyThread1 t4 = new MyThread1(d1, "Virat");
MyThread1 t5 = new MyThread1(d1, "Sachin");
MyThread1 t6 = new MyThread1(d1, "Rahul");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}
Output
Good Morning: Good Morning: Good Morning: Good Morning: Good Morning: Good
Morning: Sachin
.
.
.
Rahul
Sachin
Raina
Dhoni
Virat
10. This program demonstrates how synchronization forces threads to execute in a
serialized manner, guaranteeing predictable output and preventing interference.
package com.MutliThreading;

class Display {
public synchronized void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d1, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj

package com.MutliThreading;

class Display {
public synchronized void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
Display d2 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d2, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning: Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Yuvraj
Good Morning: Good Morning: Dhoni
Yuvraj
Good Morning: Good Morning: Yuvraj
Dhoni
Good Morning: Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Dhoni
Yuvraj

11. Even though the .wish() method is synchronized in the above program, we will get
irregular output because Threads are operating on different objects. Reason,
Synchronization is required when multiple Threads operate on the same Java object.
Synchronization is not required when multiple Threads operate on multiple Java
objects.
12. Below program demonstrates the behavior of static synchronized methods, which lock
on the class object itself, ensuring that only one thread can access any static
synchronized method of that class at a time.
package com.MutliThreading;

class Display {
public static synchronized void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}

class MyThread1 extends Thread {


Display d;
String name;

MyThread1(Display d, String name) {


this.d = d;
this.name = name;
}

@Override
public void run() {
d.wish(name);
}
}

public class SynchronziedDemo {


public static void main(String[] args) {
Display d1 = new Display();
Display d2 = new Display();
MyThread1 t1 = new MyThread1(d1, "Dhoni");
MyThread1 t2 = new MyThread1(d2, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
13. If you do not declare the .wish() method as synchronized, both Threads will execute
concurrently and we will get irregular output.
14. Every class in Java has a unique lock which is nothing but class-level lock.
15. Thread requires class level lock to execute a static synchronized method; once Thread
obtains class level lock, it is free to execute any static synchronized method of that class.
16. Once method execution completes then Thread will automatically release the lock.

17. While a Thread is executing static synchronized method the remaining Threads are not
allowed to execute any static synchronized method of that class simultaneously, but
remaining Threads are allowed to execute the following methods simultaneously.
a. Normal static()
b. Synchronized instance()
c. Normal instance()
package com.MutliThreading;

class Display2 {
public synchronized void displayN() {
for (int i = 0; i < 10; i++) {
System.out.print(i + " ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
}
}
public synchronized void displayC() {
for (int i = 65; i < 75; i++) {
System.out.print((char)i + " ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
}
}
}

class MyThread17 extends Thread {


Display2 d;
MyThread17(Display2 d) {
this.d = d;
}
@Override
public void run() {
d.displayN();
}
}
class MyThread18 extends Thread {
Display2 d;
MyThread18(Display2 d) {
this.d = d;
}
@Override
public void run() {
d.displayC();
}
}

public class SynchronizedDemo3 {


public static void main(String[] args) {
Display2 d = new Display2();
MyThread17 t1 = new MyThread17(d);
MyThread18 t2 = new MyThread18(d);
t1.start();
t2.start();
}
}
Output
0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J
6.2 Synchronized Block

1. If only a few lines of code require synchronization, it is not recommended to declare


the entire method as synchronized; instead, use a synchronized block to enclose
those few lines of code.
2. The main advantage of synchronized blocks over synchronized methods is that they
reduce thread waiting time and improve system performance.
3. To get Lock of current object

4. To get lock of particular object ‘b’


5. To get class level block

package com.MutliThreading;

class Display3 {
// ;;;;;;;;;;1 lakh lines of code
public void wish(String name) {
for (int i = 0; i < 10; i++) {
System.out.println("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
// ;;;;;;;;; l Lakh of code
}

class MyThread19 extends Thread {


Display3 d;
String name;

public MyThread19(Display3 d, String name) {


this.d = d;
this.name = name;
}
@Override
public void run() {
d.wish(name);
}
}

public class SynchronizedDemo4 {


public static void main(String[] args) {
Display3 d1 = new Display3();
Display3 d2 = new Display3();
MyThread19 t1 = new MyThread19(d1, "Dhoni");
MyThread19 t2 = new MyThread19(d1, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning:
Good Morning:
Yuvraj
Dhoni
.
.
.
Good Morning:
Yuvraj
Dhoni
Good Morning:
Good Morning:
Dhoni
Yuvraj

package com.MutliThreading;

class Display3 {
public void wish(String name) {
// l Lakh Lines of code
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(name);
}
}
}
}

class MyThread19 extends Thread {


Display3 d;
String name;

public MyThread19(Display3 d, String name) {


this.d = d;
this.name = name;
}
@Override
public void run() {
d.wish(name);
}
}
public class SynchronizedDemo4 {
public static void main(String[] args) {
Display3 d1 = new Display3();
Display3 d2 = new Display3();
MyThread19 t1 = new MyThread19(d1, "Dhoni");
MyThread19 t2 = new MyThread19(d1, "Yuvraj");
t1.start();
t2.start();
}
}
Output
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
Good Morning: Yuvraj
6. Is this valid?
package com.MutliThreading;

class Display4 {
public void wish(String name) {
// 1 Lakh lines of code
int x = 10;
synchronized (x) {

}
}
}

public class SynchronizedDemo5 {


public static void main(String[] args) {
Display4 d = new Display4();
d.wish("Dhoni");
}
}
Output
Exception in thread "main" java.lang.Error: Unresolved compilation
problem:
int is not a valid type's argument for the synchronized statement

at com.MutliThreading.Display4.wish(SynchronizedDemo5.java:7)
at
com.MutliThreading.SynchronizedDemo5.main(SynchronizedDemo5.java:16)
7. Lock concept is applicable for object types & class types but not for primitive
arguments to synchronized block otherwise we will get compile time Error saying
unexpected type found in required reference.

7 Interview Questions
1. What is synchronized keyword and where it is used?
synchronized is a modifier applicable for methods & blocks but not for class.
2. Explain advantage of synchronized keyword?
We can resolve data inconsistency problem.
3. Explain disadvantage of synchronized keyword?
It increases waiting time of the Thread and creates performance problem.
4. What is race condition?
If multiple Thread are working or operating simultaneously then there may be a
chance of data inconsistency problem.
5. How can we resolve race condition?
By using synchronized keyword.
6. What is object lock and where it is required?
Every object in Java has unique lock which is nothing but object lock wherever a
Thread wants to execute instance synchronized method then the object requires
object block.
7. What is class level lock & where it is required?
The statements present in synchronized method & synchronized block are known as
synchronized statements.

8 Inter Thread Communication

1. Two Threads can communicate with each other by using wait(), notify() & notifyAll()
methods.
2. The thread that is expecting an update is responsible for calling the wait() method.
The Thread will then enter a waiting state immediately.
3. The thread that is responsible for updating; after updating, it is responsible for calling
the notify() method. The waiting Thread will then receive that notification and
resume its execution with the updated items.
8.1 wait(), notify() & notifyAll()
1. wait(), notify() & notifyAll() methods are present in which class?
They are present in Object class but not in Thread class.
2. Why these methods are present in Object class and not in Thread class?
wait(), notify() & notifyAll() methods are present in Object class and not in Thread
class. Because Thread can call these methods on any Java Object.
3. To call wait(), notify() & notifyAll() methods on any Object. Thread should be owner
of that Object i.e.; The Thread should be inside synchronized area. Hence, we can call
wait(), notify() & notifyAll() methods only from synchronized area. Otherwise, we
will get Runtime Exception saying IllegalMonitorException.

4. If a Thread calls .wait() method on any Object it immediately releases the lock of
that particular object & enters into waiting state.
5. When a Thread invokes notify() method on an Object, it releases the lock of that
Object, though the release might not occur immediately. Apart from wait(), notify()
& notifyAll() methods, no other method exists where a Thread releases the lock.
Methods Does Thread release the lock
yield() No
join() No
sleep() No
wait() Yes
notify() Yes
notifyAll() Yes

6. Which of the following is valid?


a. If a Thread, calls wait() immediately it will enter into waiting state without
releasing lock. → invalid
b. If a Thread, calls wait() it releases the lock of that object but may not release the
lock immediately → invalid
c. If a Thread, calls wait() on any object it releases all lock acquired by that
particular object and immediately enters into waiting state → invalid
d. If a Thread, calls notify() on any object it immediately releases the lock of that
particular object and enters into waiting state → valid
e. If a Thread, calls notify() on any object it immediately releases the lock of that
particular object → invalid
f. If a Thread, calls notify() on any Object it releases the lock of object but may not
immediately → valid
7. wait method syntax
a. public final void wait() throws InterruptedException
b. public final native void wait(long ms) throws InterruptedException
c. public final void wait(long ms, int ms) throws InterruptedException
8. notify method syntax
a. public final native void notify();
b. public final native void notifyAll();
9. Note
a. Every wait() method throws InterruptedException which is Checked Exception.
Hence, whenever we are using wait method compulsory, we must handle this
Interrupted exception by try catch or by throws keyword otherwise we will get
compile time error.
10.Thread Life Cycle of wait method

package com.MutliThreading;

class ThreadB extends Thread {


int total = 0;

@Override
public void run() {
for (int i = 0; i <= 100; i++) {
total += i;
}
}
}

public class ThreadA {


public static void main(String[] args) throws InterruptedException{
ThreadB b = new ThreadB();
b.start();
System.out.println(b.total);
}
}
// 0
// 5050
// 0 <= x <= 5050
Output
0

package com.MutliThreading;

class ThreadB extends Thread {


int total = 0;

@Override
public void run() {
for (int i = 0; i <= 100; i++) {
total += i;
}
}
}

public class ThreadA {


public static void main(String[] args) throws InterruptedException{
ThreadB b = new ThreadB();
b.start();
Thread.sleep(10000);
System.out.println(b.total);
}
}
Output
5050

package com.MutliThreading;

class ThreadB extends Thread {


int total = 0;

@Override
public void run() {
for (int i = 0; i <= 100; i++) {
total += i;
}
}
}

public class ThreadA {


public static void main(String[] args) throws InterruptedException{
ThreadB b = new ThreadB();
b.start();
b.join();
System.out.println(b.total);
}
}
Output
5050

package com.MutliThreading;

class ThreadB extends Thread {


int total = 0;

@Override
public void run() {
for (int i = 0; i <= 100; i++) {
total += i;
}
this.notify();
}
}

public class ThreadA {


public static void main(String[] args) throws InterruptedException{
ThreadB b = new ThreadB();
b.start();
b.wait();
System.out.println(b.total);
}
}
Output
Exception in thread "main" Exception in thread "Thread-0"
java.lang.IllegalMonitorStateException: current thread is not owner
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:338)
at com.MutliThreading.ThreadA.main(ThreadA.java:19)
java.lang.IllegalMonitorStateException: current thread is not owner
at java.base/java.lang.Object.notify(Native Method)
at com.MutliThreading.ThreadB.run(ThreadA.java:11)

package com.MutliThreading;

public class ThreadAA {


public static void main(String[] args) throws InterruptedException {
ThreadBB b = new ThreadBB();
b.start();
synchronized (b) {
System.out.println("main thread trying to call wait()
method"); // 1
//b.wait();
b.wait();
System.out.println("main thread got the notification");//4
System.out.println(b.total);
}
}
}

class ThreadBB extends Thread{


int total = 0;
@Override
public void run() {
synchronized (this) {
System.out.println("child Thread start calculation"); //2
for (int i = 1; i <= 100; i++) {
total += i;
}
System.out.println("child thread trying to give the
notification"); //3
this.notify();
}
}
}
Output
main thread trying to call wait() method
child Thread start calculation
child thread trying to give the notification
main thread got the notification
5050

package com.MutliThreading;

public class ThreadAA {


public static void main(String[] args) throws InterruptedException {
ThreadBB b = new ThreadBB();
b.start();
Thread.sleep(10000);
synchronized (b) {
System.out.println("main thread trying to call wait()
method"); // 3
//b.wait();
b.wait();
System.out.println("main thread got the notification");
System.out.println(b.total);
}
}
}

class ThreadBB extends Thread{


int total = 0;
@Override
public void run() {
synchronized (this) {
System.out.println("child Thread start calculation"); //1
for (int i = 1; i <= 100; i++) {
total += i;
}
System.out.println("child thread trying to give the
notification"); //2
this.notify();
}
}
}
Output
child Thread start calculation
child thread trying to give the notification
main thread trying to call wait() method
8.2 Producer Consumer Problem

1. Producer Thread is responsible to produce items to the Queue and Consumer Thread
is responsible to consume items from the Queue.
2. If Queue is empty, then consumer thread will call wait() method and enters into
waiting state.
3. After Producing items to the Queue, producer thread is responsible to call notify()
method then waiting consumer will get that notification and continue its execution
with updated items.
8.3 Difference between notify() and notifyAll()
1. We can use notify() method to give notification to only one thread then only one
thread will be notified and the remaining threads have to wait for further
notification.
2. Which Thread will be notified, we cannot expect and it depends on JVM.
3. We can use notifyAll() method to give the notification to all the Threads of a
particular object, then even though multiple threads notified but execution will be
performed one by one because Threads require lock and only one lock is available.

9 Deadlock
1. If two Threads are waiting for each other forever such type of infinite waiting is
Deadlock.
2. synchronized keyword is the only reason for deadlock situation. Hence, while using
synchronized keyword we have to take special care.
3. There are no resolution technique for deadlock but several prevention techniques are
available.
package com.MutliThreading;

class A {
public synchronized void d1(B b) {
System.out.println("Thread 1 starts execution of d1() method");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println("Thread 1 trying to call B's Last()");
b.last();
}

public synchronized void last() {


System.out.println("Inside A, this is last() method");
}
}
class B {
public synchronized void d2(A a) {
System.out.println("Thread 2 starts execution of d2() method");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println("Thread 2 trying to call A's Last()");
a.last();
}

public synchronized void last() {


System.out.println("Inside B, this is last() method");
}
}

public class Deadlock extends Thread{


A a = new A();
B b = new B();

public void m1() {


this.start();
a.d1(b); // This line executed by main Thread
}
@Override
public void run() {
b.d2(a); // This line executed by child Thread
}
public static void main(String[] args) {
Deadlock d = new Deadlock();
d.m1();
}
}
Output
Thread 1 starts execution of d1() method
Thread 2 starts execution of d2() method
Thread 1 trying to call B's Last()
Thread 2 trying to call A's Last()
4. In the above program, if we remove atleast one synchronized keyword then the
program will not enter into deadlock situation. So due to this, while using
synchronized keyword we have to take special care.
Output after removing one synchronized keyword
Thread 1 starts execution of d1() method
Thread 2 starts execution of d2() method
Thread 1 trying to call B's Last()
Inside B, this is last() method
Thread 2 trying to call A's Last()
Inside A, this is last() method
9.1 Deadlock vs Starvation
1. Long waiting of a Thread, where waiting never ends is called Deadlock whereas long
waiting of a Thread where waiting ends at a certain point is called Starvation.
For E.g., Low priority Thread has to wait for High priority Threads it may be long
waiting but ends at certain point which is nothing but starvation.

10 Daemon Threads
1. The Threads which are executing in the background are called Daemon Threads.
E.g., Garbage collector, Attach listener & Signal dispatcher.

2. The main objective of Daemon Thread is to provide support for non-Daemon Threads
(Main Thread).
For E.g., If Main Thread runs with low memory, then JVM runs garbage collector to
destroy useless objects. So that number of bytes of free memory will be improved.
With this free memory main thread can continue its execution.
3. Usually, Daemon Threads have low priority but based on our requirement daemon
thread can run with high priority also.
4. We can check Daemon nature of a Thread by using isDaemon() of a Thread class.
5. We can change Daemon nature of a Thread by using setDaemon() method.
6. But changing Daemon nature is possible before starting of a Thread only after starting
a Thread if we are trying to change Daemon nature, then we will get
RuntimeException saying IllegalThreadStateException.
public boolean isDaemon()
public void setDaemon(boolean b)
10.1 Default nature of Thread
1. By default, Main Thread is always Non-Daemon and for all remaining threads
Daemon nature will be inherited from parent to child i.e., If parent thread is Daemon
then automatically child thread is also Daemon and if parent thread is Non-Daemon
then automatically child thread is also Daemon.
2. Note: - It is impossible to change Daemon nature of Main Thread because it is
already started by JVM at beginning.
package com.MutliThreading;

class MyThread900 extends Thread {

public class Check {


public static void main(String[] args) {
System.out.println(Thread.currentThread().isDaemon());
// Thread.currentThread().setDaemon(true); //
java.lang.IllegalThreadStateException
MyThread900 t = new MyThread900();
System.out.println(t.isDaemon());
t.setDaemon(true);
System.out.println(t.isDaemon());
t.start();
t.setDaemon(false);
}
}
Output
false
false
true
Exception in thread "main" java.lang.IllegalThreadStateException
at java.base/java.lang.Thread.setDaemon(Thread.java:1403)
at com.MutliThreading.Check.main(Check.java:16)
3. Whenever last non daemon threads terminate automatically all daemon Threads will
be Terminated irrespective of their position.
package com.MutliThreading;

class MyThread21 extends Thread {


@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}
}

public class DaemonThread {


public static void main(String[] args) {
MyThread21 t = new MyThread21(); // Non Daemon
// t.setDaemon(true); // ----> Line 1
t.start();
System.out.println("End of Main Thread");
}
}
4. If we are commenting Line 1 both Main Thread and Child Thread are Non-Daemon
and both Child Threads will be executed until their completion in this case output is:
End of Main Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
5. If we are not commenting Line 1 Main Thread will be non-daemon and child thread
will be daemon. Hence, whenever main thread terminates automatically child thread
will be terminated in this case output is:
End of Main Thread
Child Thread
Or
Child Thread
End of Main Thread
Or
End of Main Thread

11 Mutlithreading Models

1. Green Thread Model :


a. The Thread which is managed completely by JVM without taking underlying OS
support is called Green Thread.
b. Very few OS like SUN Solaris provide support for Green Thread Model anyway
Green Thread Model is deprecated and not recommended to use.
2. Native OS Model :
a. The Thread which is managed by the JVM with the help of underlying OS is
called Native OS Model.
b. All windows-based OS provides support for Native OS Model.

12 How to stop a Thread

package com.MutliThreading;

class MyThread90 extends Thread {


@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child-Thread");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}
}

public class Test {


public static void main(String[] args) {
MyThread90 t = new MyThread90();
t.start();
System.out.println("End of Main Thread");
t.stop();
}
}
Output
End of Main Thread
Child-Thread
1. We can stop a Thread execution by using stop() method of a Thread class.
public void stop()
2. If we call stop() then Thread will immediately enter into Dead state any way stop() is
deprecated and not recommended to use.
3. How to suspend and resume a Thread?
a. public void suspend();
b. public void resume();

c. We can suspend a Thread by using suspend() method of a Thread class, then


immediately the Thread will enter into suspended state.
d. We can resume a suspended Thread by using resume() method of Thread class, then
the Thread can resume its execution.
e. Note: - Anyway these methods are deprecated and not recommended to use.
13 Mutlithreading Enhancement
13.1 Thread Groups
1. Based on functionality we can group threads into a single unit which is nothing but
Thread Group.
2. Thread Group contains a group of Threads in addition to Threads, thread group can
also contain sub thread group.
3. The main advantage of maintaining threads group is we can perform common
operation very easily.
4. In java every thread is child group of system group directly or indirectly.

package com.MutliThreading;

public class Test {


public static void main(String[] args) {
System.out.println(Thread.currentThread().getThreadGroup().getName());

System.out.println(Thread.currentThread().getThreadGroup().getParent()
.getName());
}
}
Output
main
system
5. Every Thread in Java Belongs to some group, main thread belongs to main group.
6. Every Thread group in java is the child group of system group. Hence, system group
acts as root for all thread groups in java.
7. System group thread contains several system level threads like
a. finalizer
b. reference handler
c. signal dispatcher
d. attach listener etc.,

8. Thread Group is a Java class present in java.lang package and it is direct child class of
Object.
9. Constructors
a. ThreadGroup g = new ThreadGroup(String Groupname);
E.g.,
ThreadGroup g = new ThreadGroup(“First Group”);
Creates a new ThreadGroup with the specified group name. The parent of this
new Group is ThreadGroup of currently executing Thread.
package com.MutliThreading;

public class Test {


public static void main(String[] args) {
ThreadGroup g = new ThreadGroup("First Group");
System.out.println(g.getParent().getName());
}
}
Output
main
b. ThreadGroup g = new ThreadGroup(ThreadGroup pg, String GroupName);
E.g.,
ThreadGroup g1 = new ThreadGroup(g1, SecondGroup);
Creates a new ThreadGroup with the specified groupname the parent of this new
ThreadGroup is specified Parent Group.
package com.MutliThreading;

public class Test {


public static void main(String[] args) {
ThreadGroup g = new ThreadGroup("First Group");
System.out.println(g.getParent().getName());
ThreadGroup g2 = new ThreadGroup(g,"Second Group");
System.out.println(g2.getParent().getName());
System.out.println(g2.getName());
}
}
Output
main
First Group
Second Group
10. Important Methods of ThreadGroup class
a. String getName(); - Returns Name of the Thread Group
b. int getMaxPriority(); - Returns Max Priority of a Thread.
c. void setMaxPriority(); - To set maximum priority of a Thread, The Default Max
Priority of a Thread is 10.
package com.MutliThreading;

public class Test {


public static void main(String[] args) {
ThreadGroup g1 = new ThreadGroup("tg");
Thread t1 = new Thread(g1, "First Thread");
Thread t2 = new Thread(g1, "Second Thread");
g1.setMaxPriority(3);
Thread t3 = new Thread(g1, "Third Thread");
System.out.println(t1.getPriority());
System.out.println(t2.getPriority());
System.out.println(t3.getPriority());
}
}
Output
5
5
3
d. ThreadGroup getParent(); - Returns Parent Group of Current Thread.
e. void List(); - Prints information of about the current Thread Group.
f. int activeCount(); - Returns number of Active Threads present in the Thread
Group.
g. int activeGroupCount(); - Returns number of Active Groups present in the current
Thread Group.
package com.MutliThreading;

class MyThread23 extends Thread {


public MyThread23(ThreadGroup g, String name) {
super(g, name);
}
@Override
public void run() {
System.out.println("Child Thread");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
}
}

public class ThreadGroupDemo2 {


public static void main(String[] args) throws
InterruptedException{
ThreadGroup pg = new ThreadGroup("Parent Group");
ThreadGroup cg = new ThreadGroup(pg, "Child Group");
MyThread23 t1 = new MyThread23(pg, "Child Thread1");
MyThread23 t2 = new MyThread23(pg, "Child Thread2");
t1.start();
t2.start();
System.out.println(pg.activeCount());
System.out.println(pg.activeGroupCount());
pg.list();
Thread.sleep(6000);
System.out.println(pg.activeCount());
System.out.println(pg.activeGroupCount());
pg.list();
}
}
Output
2
Child Thread
Child Thread
1
java.lang.ThreadGroup[name=Parent Group,maxpri=10]
Thread[Child Thread1,5,Parent Group]
Thread[Child Thread2,5,Parent Group]
java.lang.ThreadGroup[name=Child Group,maxpri=10]
0
1
java.lang.ThreadGroup[name=Parent Group,maxpri=10]
java.lang.ThreadGroup[name=Child Group,maxpri=10]
h. int enumerate(Thread[] t); - To copy all active threads of this thread group into
provided thread array in this subThreadGroup threads will be considered.
i. int enumerate(ThreadGroup[] g); - To copy all subThread Groups into Thread
Group Array.
j. Boolean isDaemon(); - To check whether the Thread Group is daemon or not.
k. void setDaemon(boolean b); - We can change Daemon nature of this thread
group.
l. void interrupt(); - To interrupt all waiting or sleeping threads present in the
ThreadGroup.
m. void destroy(); - To destroy ThreadGroup and its SubThreadGroup.

You might also like