0% found this document useful (0 votes)
586 views

Multi Threading in Java by Durga Sir

The document discusses multi-threading in Java. It covers defining threads by extending the Thread class or implementing Runnable, thread priorities, methods to control thread execution like yield(), join(), and sleep(), synchronization, inter-thread communication, deadlocks, and daemon threads.

Uploaded by

Lalit
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
586 views

Multi Threading in Java by Durga Sir

The document discusses multi-threading in Java. It covers defining threads by extending the Thread class or implementing Runnable, thread priorities, methods to control thread execution like yield(), join(), and sleep(), synchronization, inter-thread communication, deadlocks, and daemon threads.

Uploaded by

Lalit
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 75

Multi Threading in java

1. Introduction
2. The ways to define a thread
 By extending a thread class
 By implementing Runnable Interface
3. Getting and setting name of threads
4. Thread priorities
5. The method to prevent thread execution
 Yield()
 Join()
 Sleep()
6. Synchronization
7. Interthread communication
8. Deadlock
9. Daemon thread
10. Multithreading enhancement
Introduction :

Multitasking :

Executing several tasks simultaneously is the concept of multi-tasking.

There are two types of multitasking.

1. Process based multitasking


2. Thread based multitasking

Process based multitasking:


1. Executing several tasks simultaneously where each task is a separate
independent program (process) is called process based multitasking.
2. Process based multi-tasking is best suitable yet OS (operating system)
level.

Example:

1. While typing is a java program in the editor we can listen audio songs
from the same system.
2. At the same time we can download a file from internet. All these tasks
will be executed simultaneously and independent of each other. Hence it
is process based multi-tasking.

Thread based multitasking:


1. Executing several tasks simultaneously where each task is a separate
independent part of the same program is called thread based
multitasking and each independent part is called a thread.
2. Thread based multitasking is best suitable yet programmatic level.

 Whether it is process based or thread based, the main objective of


multitasking is to reduce response time of the system and to improve
performance.
 The main important application areas of multi threading are
1. To develop multimedia graphics.
2. To develop animation.
3. To develop video games.
4. To develop web servers and application servers etc.
 When compared with old languages developing multithreaded application
in java is very easy because java provides inbuilt support for
multithreading with rich API (Thread, Runnable, ThreadGroup).

Defining a thread:
We can define a thread in the following two ways.

 By extending Thread class


 By implementing Runnable Interface

1.By extending Thread class:

package demoThread;

// defining a thread
public class MyThread extends Thread {
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("child-thread"); // job of child thread
and executed by child thread
}
}
}

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread(); // instantiation of main thread and
till here only one thread that is main thread
t.start(); // starting of child thread by main thread using
start() method and after t.start(), there is two thread, one is main
and 2nd is child
main thread

after t.start()

for(int i = 0; i < 5; i++) { main thread child thread


System.out.println("main-child"); // this job executed by
main thread
}
}
}

Output:

main-child
main-child
main-child
main-child
main-child
child-thread
child-thread
child-thread
child-thread
child-thread

Thread scheduler:
It is the art of JVM and it is responsible to schedule threads i.e if
multiple threads are waiting to get the chance of execution then in which
order threads will be executed is decided by thread scheduler.

We can’t expect exact algorithm followed by thread scheduler. It is varied


from JVM to JVM. Hence we can’t expect thread execution order and exact
output.

Hence whenever situation comes to multi threading, there is no guarantee for


exact output but we can provide several possible outputs.

main-child child-thread main-child child-thread main-child


main-child child-thread child-thread main-child child-thread
main-child child-thread main-child child-thread child-thread
main-child child-thread child-thread main-child child-thread
main-child child-thread main-child child-thread child-thread
child-thread main-child child-thread main-child child-thread
child-thread main-child main-child child-thread main-child
child-thread main-child child-thread main-child main-child
child-thread main-child main-child child-thread main-child
child-thread main-child child-thread main-child main-child

Case2:

Difference t.start() and t.run():


In the case of t.start() a new thread will be created which is the
responsible for the excecution of run method.

But in the case of t.run() a new thread won’t be created and run() method
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();

package demoThread;

// defining a thread
public class MyThread extends Thread {
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("child-thread"); // job of child thread
and executed by main thread
}
}
}

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread(); // till here only one thread that is
main thread
t.run(); // after t.run(),run() method will be executed just like a
normal method call by main thread.

for(int i = 0; i < 5; i++) {


System.out.println("main-child"); // this job executed by
main thread
}
}
}

then the output is

child-thread
child-thread
child-thread
child-thread
child-thread
main-child
main-child
main-child
main-child
main-child

This total output produced by only main thread.

Case3:

Importance of Thread class start() method:


Thread class start() method is responsible to register the Thread with Thread
scheduler and all other mandatory activities. Hence without executing Thread
class start() method there is no chance of starting a new Thread in java. Due
to this Thread class start() is considered as heart of multithreading.

Start() {

1. Register this thread with thread scheduler


2. Perform all other mandatory activities
3. Invoke run() method

}
Case4:

Overloading of run() method:


1. Overloading of run() method is always possible but Thread class start()
method can invoke no argument run() method.
2. The other overloaded run() method we have to call explicitly like a
normal method call.

package demoThread;

public class MyThread extends Thread {

public void run() {


System.out.println("no-arg");
}

public void run(int i) {


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

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();

t.run(10);
}
}

Output:

int-arg
no-arg

Case5:
If we are not overriding run() method:

If we are not overriding run() method then Thread class run() method
will be executed which has empty implementation. Hence we won’t get any
output.

package demoThread;

public class MyThread extends Thread {

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();

}
}

No output.

It is highly recommended to override run() method, otherwise don’t go


for multithreading concept.

Case6:

Overriding of start() method:


If we override start() method then our start() method will be executed
just like a normal method call and new thread won’t be created.

package demoThread;

public class MyThread extends Thread {


public void start()
{
System.out.println("start method");
}
@Override
public void run() {
System.out.println("run method");

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();

System.out.println("main-method");
}

Output:

start-method produced by only main thread


main-method

In this program we create child class object. So t.start() statement will


execute 1st start() method of child class.

Note:

It is not recommended to override start() method, otherwise don’t go for


multi threading concept.
Case7:

package demoThread;

public class MyThread extends Thread {

public void start() {


super.start();
System.out.println("start-method");
}

public void run() {


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

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();

System.out.println("main-method");
}

}
Possible outputs:

start-method start-method run-method


run-method main-method start-method
main-method run-method main-method

Case8:

Thread Life Cycle:


MyThread t = new MyThread();

New/born

t.start();

ready/born

if t.start() allocates processor

running

if run() method complete

Dead
Case9:

After starting a thread if we are trying to re-start the same thread then we
will get RunTimeException saying IllegalThreadStateException.

package demoThread;

public class MyThread extends Thread {

public void run() {


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

package demoThread;

public class ThreadDemo {

public static void main(String[] args) {


MyThread t = new MyThread();
t.start();

t.start();

System.out.println("main-method");
}

Output:

Exception in thread "main" run-


methodjava.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:708)
at demoThread.ThreadDemo.main(ThreadDemo.java:8)
Defining a Thread by implementing Runnable Interface:
1. We can define a Thread by implementing Runnable Interface.

Approach 1st:

MyThread Thread Runnable Interface

Approach 2nd:

MyThread Runnable Interface

2. Runnable Interface present in java.lang package and it contains only


one method run() method.

package demoThread;

public class MyThread implements Runnable{

public void run() {


for(int i = 0; i < 5; i++) {
System.out.println("child thread");
}
}
}

package demoThread;

public class ThreadDemo {

public static void main(String[] args) {

MyThread t = new MyThread();// this statement will execute main


thread and main thread will create MyThread class object

Thread t1 = new Thread(t); // to execute a run() method we need a


start() method and start() method is belong to Thread class, so we
have to create Thread class object
// if we call start() method directly created by Thread class object
then it execute only Thread class run() method, which has empty
implementation
// so to execute MyThread class run() method we have to do object type
casting

t1.start();

for(int i = 0; i < 5; i++) {


System.out.println("main thread");
}

Possible outputs:

main-child child-thread main-child child-thread main-child


main-child child-thread child-thread main-child child-thread
main-child child-thread main-child child-thread child-thread
main-child child-thread child-thread main-child child-thread
main-child child-thread main-child child-thread child-thread
child-thread main-child child-thread main-child child-thread
child-thread main-child main-child child-thread main-child
child-thread main-child child-thread main-child main-child
child-thread main-child main-child child-thread main-child
child-thread main-child child-thread main-child main-child

We will get mixed output and we can’t tell exact output.

Case Study:
MyThread t1 = new MyThread();

Thread t2 = new Thread();

Thread t3 = new Thread(t1);


Case1: Runnable Target

t2.start();--- A new thread will be created and which is responsible


for the execution of Thread class run() method, which has empty
implementation.

Case2:

t2.run();--- No new thread will be created and Thread class run() will
be executed just like a normal method call.

Case3:

t3.start();--- A new thread will be created which is responsible for


the execution of Mythread class run() method.

Case4:

t3.run();--- No new thread won’t be created and MyThread class run()


method just like a normal method call.

Case5:

t1.start();--- we will get compile time error saying MyThread class


doesn’t start capability.

Exception in thread "main" java.lang.Error: Unresolved compilation


problem: The method start() is undefined for the type MyThread
at demoThread.ThreadDemo.main(ThreadDemo.java:9)

Case6:

t1.run();--- No new thread will be create and MyThread class run() method
will be executed just like a normal method call.

Q:Which approach is best to define a Thread?

Answer:

1. Among two ways of defining a Thread implements Runnable Interface


approach is recommended.
2. In the 1st approach our class always extends Thread class, there is no
chance of extending any other class. Hence we are missing inheritance
benefit.
3. But in the 2nd approach while implementing Runnable Interface we can
extend any other class. Hence we won’t miss any inheritance benefit.
4. Because of above reason implementing Runnable Interface approach is
recommended then extending Thread class.

Thread class constructors:


 Thread t2 = new Thread();
 Thread t2 = new Thread(Runnable t1);
 Thread t2 = new Thread(String name);
 Thread t2 = new Thread(Runnable t1, String name);
 Thread t2 = new Thread(ThreadGroup g, String name);
 Thread t2 = new Thread(ThreadGroup g, Runnable t1);
 Thread t2 = new Thread(ThreadGroup g, Runnable t1, String name);
 Thread t2 = new Thread(ThreadGroup g, Runnable t1, String name, long
stackSize);

Durga’s approach to define a Thread (Not recommended to use):

package demoThread;

public class MyThread extends Thread {

public void run() {

System.out.println("child thread");
}
}

package demoThread;

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");
}
}

Possible output:

main Thread child thread


child thread main Thread

MyThread Thread Runnable

Getting and Setting name of a Thread:


Every Thread in java has some name. It may be default name generated by
JVM or customized name provided by programmer.
We can get and set name of a Thread by using the following two methods
Thread class.
 Public final String getName()
 Public void setNameOfAStringName()

package demoThread;

public class MyThread extends Thread {

package demoThread;

public class ThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName());

MyThread t = new MyThread();


System.out.println(t.getName());

MyThread t1 = new MyThread();


System.out.println(t1.getName());

Thread.currentThread().setName("Lalit Bizlain");
System.out.println(Thread.currentThread().getName());

System.out.println(10/0);

}}
Output:

main
Thread-0
Thread-1
Lalit Bizlain
Exception in thread "Lalit Bizlain" java.lang.ArithmeticException: /
by zero
at demoThread.ThreadDemo.main(ThreadDemo.java:18)

Note:

We can get current executing Thread object by using Thread.currentThread()


method.

package demoThread;

public class MyThread extends Thread {

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

package demoThread;

public class ThreadDemo {

public static void main(String[] args) {


MyThread t = new MyThread();
t.start();
System.out.println("main method executed by Thread " +
Thread.currentThread().getName());

}
}

Output:
main method executed by Thread main
run method executed by Thread Thread-0

Thread Priorities:
Every Thread in java has some priority. It may be default priority
generated by JVM or customized priority provided by programmer.

The valid range of Thread Priority is 1 to 10. Where 1 is minimum


priority and 10 is maximum priority.

Thread class defines the following constants to represent some


standard priorities.

 Thread.MIN_PRIORITY = 1
 Thread.NORM_PRIORITY = 5
 Thread.MAX_PRIORITY = 10

Q: which are the valid Thread Priorities?

 Thread.LOW_PRIORITY
 Thread.HIGH_PRIORITY
 Thread.MIN_PRIORITY
 Thread.NORM_PRIORITY

 Thread scheduler will used priorities while allocating processor.


 The Thread which is having highest priority will get chance 1 st.
 If two Threads having same priority then we can’t expect exact
execution order. It depends on Thread scheduler.
 Thread class defines the following methods to get and set priority of a
Thread:
 Public final int getPriority();
 Public final void setPriority(int p);

Allowed values range 1 to 10, otherwise


RunTimeException: IllegalArgumentException

package demoThread;

public class ThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.setPriority(7);-------------------valid

t.setPriority(17);------------------invalid

}
}

 The default priority only for the main Thread is 5. For all remaining
Threads default priority will be inherited from parent to child i.e
whatever priority parent Thread has, the same priority will be there
for the child Thread.

package demoThread;

public class MyThread extends Thread {

package demoThread;

public class ThreadDemo {

public static void main(String[] args) {


System.out.println(Thread.currentThread().getPriority());
Thread.currentThread().setPriority(7);---------------------1
// Thread.currentThread().setPriority(15);
MyThread t = new MyThread();
System.out.println(t.getPriority());

}
}

Output:

5
7

If we comment line 1 then child Thread priority will become 5.


MyThread t = new MyThread(); parent class Thread

Parent Thread Main Thread

package demoThread;

public class MyThread extends Thread {

@Override
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("child thread");
}
}

package demoThread;

public class ThreadPrioritiesDemo {

public static void main(String[] args) {

MyThread t = new MyThread();


t.setPriority(10);--------------1
t.start();

for(int i = 0; i < 5; i++) {


System.out.println("main thread");
}

}
}

Output:

Child thread
Child thread
Child thread
Child thread
Child thread
main thread
main thread
main thread
main thread
main thread

If we are commenting line 1 then both main and child threads have the same
priority 5 and hence we can’t expect execution order and exact output.

If we are not commenting line 1 then main thread has a priority 5 and child
thread has the priority 10. Hence child thread will get the chance 1 st
followed by main thread.

In this case output is

We can prevent a Thread execution by using the following methods:

 Yield() method
 Join() method
 Sleep() method

1.Yield() method:
 Yield() method causes "to pause current executing Thread for
giving the chance of remaining waiting Threads of same priority".
 If there is no waiting Thread or all waiting Threads are low
priority then same Thread can continue its execution.
 If several waiting Threads with the same priority
available/waiting then we can't expect exact which Thread will
get chance for execution. It depends on Thread scheduler.

 The Thread which is yielded when it gets chance once again for
execution. It depends on the mercy of the Thread scheduler.

public static native void yield();


MyThread t = new MyThread();

New/born

t.start();

ready/runnable

if thread scheduler allocate processor

running

if run() method complete

dead

package demoThread;

public class MyThread extends Thread {

@Override
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("child thread");
Thread.yield();------------------------1
}
}

package demoThread;
public class ThreadYieldDemo {

public static void main(String[] args) {

MyThread t = new MyThread();

t.start();

for(int i = 0; i < 5; i++) {


System.out.println("main thread");
}

}
}

Output:
main thread
main thread
main thread
main thread
child thread
main thread
child thread
child thread
child thread
child thread

 In the above program if we are commenting line 1 then both threads will
be executed simultaneously and we can’t expect which Thread will
complete 1st.
 If we are not commenting line 1 then child Thread always call yield()
method because of that main Thread will get chance more number of times
and the chance of completing main Thread 1st is high.
 Some platforms won’t provide proper support for yield method.

2.Join() method:
 If a Thread wants to wait until completing some other Thread then we
should go for join() method.

Example:

 If a Thread t1 wants to wait until completing t2 then t1 has to call


t2.join().
 If t1 executes t2.join() then immediately t1 will be entered into
waiting state until t2 completes.
 Once t2 completes then t1 can continue its execution.
Example:

Venue fixing activity (t1)

Wedding cards printing (t2)


t1.join();

Wedding cards distribution (t3)


t2.join();

 Wedding cards printing Thread (t2) has to wait until venue fixing
Thread (t1) completion. Hence t2 has to call t1.join().
 Wedding cards distribution Thread (t3) has to wait until wedding
cards printing Thread (t2) completion. Hence t3 has to call
t2.join().

Method signature of join() method:

 public final void join() throws InterruptedException


 public final void join(long milliseconds) throws
InterruptedException
 public final void join(long milliseconds, int nanoseconds) throws
InterruptedException

Note:
Every join method throws interrupted exception which is checked
exception. Hence compulsory we should handle this exception either by
try-catch or by throws keyword, otherwise we will get compile time
error.

MyThread t = new MyThread();

New/born

t.start();

ready/runnable

if thread scheduler allocate processor

running

if run() method complete

dead

Example1: waiting Thread without time period or wait until completing


another Thread.

package demoThread;
public class MyThread extends Thread {

@Override
public void run() {

for(int i = 0; i < 5; i++) {

System.out.println("sheeta thread");

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}

package demoThread;

public class ThreadYieldDemo {

public static void main(String[] args) throws InterruptedException {

MyThread t = new MyThread();

t.start();

t.join();-------------------------1

for(int i = 0; i < 5; i++) {


System.out.println("Ram thread");
}

}
}
 If we comment line 1 then both main and child threads will be
executed simultaneously and we can’t expect exact output.
 If we are not commenting line 1 then main thread calls method on
child thread. Hence main thread will wait until child thread
output is
Output:

sheeta thread
sheeta thread
sheeta thread
sheeta thread
sheeta thread
Ram thread
Ram thread
Ram thread
Ram thread
Ram thread

Example2: waiting Thread with time period or wait for some time either
another Thread complete or not.

package demoThread;

public class MyThread extends Thread {

@Override
public void run() {

for(int i = 0; i < 5; i++) {

System.out.println("sheeta thread");

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}

package demoThread;

public class ThreadYieldDemo {

public static void main(String[] args) throws InterruptedException {


MyThread t = new MyThread();

t.start();

t.join(5000);--------------1

for(int i = 0; i < 5; i++) {


System.out.println("Ram thread");
}

}
}
 If we comment line 1 then both main and child threads will be
executed simultaneously and we can’t expect exact output.
 If we are not commenting line 1 then main thread calls method on
child thread. Hence main thread will wait until child thread
output is

Output:

sheeta thread
sheeta thread
sheeta thread
Ram thread
Ram thread
Ram thread
Ram thread
Ram thread
sheeta thread
sheeta thread

Example3: Waiting child Thread until completing main Thread.

package demoThread;

public class MyThread extends Thread {


static Thread mt;
@Override
public void run() {
try {
mt.join();
} catch (InterruptedException e) {
// TODO: handle exception
}

for(int i = 0; i < 5; i++) {


System.out.println("child thread");
}
}
}

package demoThread;

public class ThreadJoinDemo {

public static void main(String[] args) throws InterruptedException {

MyThread.mt = Thread.currentThread();
MyThread t = new MyThread();

t.start();

for(int i = 0; i < 5; i++) {


System.out.println("main thread");
Thread.sleep(2000);
}

}
}

In the above example child Thread calls join() method on main Thread
object. Hence child Thread has to wait until completing main Thread.
In this case output is

Output:
main thread
main thread
main thread
main thread
main thread
child thread
child thread
child thread
child thread
child thread

Example4:

If main Thread calls join() method on child Thread object and child
Thread call join() on main Thread object then both Threads will wait
forever and the program will be stuck (This is something like
Deadlock).

package demoThread;

public class MyThread extends Thread {

static Thread mt;


@Override
public void run() {
try {
mt.join();
} catch (InterruptedException e) {
// TODO: handle exception
}

for(int i = 0; i < 5; i++) {


System.out.println("child thread");
}
}
}

package demoThread;

public class ThreadJoinDemo {

public static void main(String[] args) throws InterruptedException {


MyThread.mt = Thread.currentThread();
MyThread t = new MyThread();

t.start();
t.join();

for(int i = 0; i < 5; i++) {


System.out.println("main thread");
Thread.sleep(2000);
}

}
}

Example5:

If a Thread calls join() method on the same Thread itself then the
program will be stuck (This is something like Deadlock).

package demoThread;

public class ThreadJoinDemo {

public static void main(String[] args) throws InterruptedException {

Thread.currentThread().join();
}
}

In this case Thread has to wait infinite amount of time.

Sleep() method
1. If a Thread don’t want to perform any performance for a particular
amount of time then we should go for sleep() method.

 public static native sleep(long milliseconds) throws


InterruptedException
 public static void sleep(long milliseconds, int nanoseconds) throws
InterruptedException

Note:

Every sleep() method throws InterruptedException, which is checked exception.


Hence whenever we are using sleep() method, compulsory we should handle
Interrupted Exception either by try catch or by throws keyword, otherwise we
will get compile time error.

package demoThread;

public class ThreadRotater {

public static void main(String[] args) throws InterruptedException {

for(int i = 0; i < 5; i++) {


System.out.println("slide " + i);
Thread.sleep(5000);
}

}
}

Output:

slide 0
slide 1
slide 2
slide 3
slide 4

How a Thread can interrupt another Thread:


A thread can interrupt a sleeping Threading or a waiting Thread by using
interrupt method of Thread class.

Public void interrupt()

package demoThread;
public class MyThread extends Thread {

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

}
}

package demoThread;

public class ThreadSleepDemo {

public static void main(String[] args) {

MyThread t = new MyThread();


t.start();

t.interrupt();------------------1

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


}
}

If we comment line 1 then main Thread won’t interrupts child Thread.


In this case, child Thread will execute for loop 10 times.
If we are not commenting line 1 then main Thread interrupts child
Thread in this case output is

Output:

End of main Thread


I am Lazy Thread
I got interrupted

Note:
1. Whenever we are calling interrupt() method, if the target Thread
not in sleeping state or waiting state then there is no impact of
interrupt call immediately. Interrupt call will be waited until
target Thread entered into sleeping or waiting state.
2. If the target Thread entered into sleeping or waiting state then
immediately will interrupt target Thread.

package demoThread;

public class MyThread extends Thread {

@Override
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("I am Lazy Thread " + i);
}

System.out.println("I want to sleep");


try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("I got interrupted");
}

}
}

package demoThread;

public class ThreadSleepDemo {

public static void main(String[] args) {

MyThread t = new MyThread();


t.start();

t.interrupt();

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


}
}
Output:

End of main Thread


I am Lazy Thread 0
I am Lazy Thread 1
I am Lazy Thread 2
I am Lazy Thread 3
I am Lazy Thread 4
I want to sleep
I got interrupted

In the above example interrupt call waited until child Thread


completes for loop 5 times.

3. If the target Thread never entered into sleeping or waiting state


in its lifetime then there is no impact of interrupt call. This
is the only case where interrupt call will be waisted.

Compare yield(), sleep() and join() method:

Property Yield() Join() Sleep()


1. Purpose If a Thread wants to If a Thread wants If a Thread don’t want to
pause its execution to to wait until perform any operation for a
give the chance for completing some particular amount of time
remaining Threads of other Thread then then we should go for
same priority then we we should go for sleep() metho.
should go for yield() join() method.
method
2. Is it overload? No Yes Yes
3. Is it final? No Yes Yes
4. Is it throws No Yes Yes
InterruptedException?
5. Is it native? Yes No  Sleep(long ms)—
native
 Sleep(long ms, int
ns)— non-native

Synchronization:
1. Synchronized is the modifier applicable only for methods and blocks but
not for classes and variables.
2. If multiple Threads are trying to operate simultaneously on the same
java object then there may be a chance of data inconsistency problem.
3. To overcome this problem we should go for synchronized keyword.
4. If a method or block declared as synchronized then at a time only one
Thread is allowed to execute that method or block and given object. So
that data inconsistency problem will be resolved.
5. The main advantage of synchronized keyword is we can resolve data
inconsistency problems but the main disadvantage of synchronized
keyword is it increases waiting time of Threads and creates performance
problems. Hence if there is no specific requirement then it is not
recommended to use synchronized keyword.
6. Internally synchronization is implemented by using lock. Every object
in java has a unique lock.
7. Whenever we are using synchronized keyword then only lock concept will
come into the picture.
8. If a Thread wants to execute synchronized method on the given object,
1st it has to get lock of that object. Once Thread got the lock then it
is allowed to execute any synchronized method on that object.
9. Once method execution completes automatically Thread releases the lock.
10. Acquiring and releasing the lock, internally takes care by JVM
and programmer not responsible for this activity.
11. While a Thread executing synchronized method on the given object,
the remaining Threads not allowed to execute any synchronized method
simultaneously on the same object but remaining Threads are allowed to
execute non-synchronized method simultaneously.

package demoThread;

public class X {

synchronized void m1() {

synchronized void m2() {

void m3() {

t2 m1() X t1—object level lock(x)


t3 m2()
m1(){ }

m3()
t4

 t1 starts execution of m1() method. If t2 came to start


execution of same m1() method then t2 will in waiting
state.
 If t3 came to execute m2() method—waiting state
 t4 came to execute m3() method—valid
 Lock concept is implemented based on object but not based
on method.

Non-synchronized area synchronized area

Object

This area can be This area can be


Accessed by any no. of accessed by only
Threads simultaneously one Thread at a time

Synchronized area:
Wherever we are performing update operation
(add/remove/delete/replace) where state of object changing.

Non- Synchronized area:


Wherever state object won’t be changed like read() operation.
package demoThread;

public class TrainReservationSystem {

public void checkAvailability(){

just read operation

public synchronized void bookTicket() {

update

Example:
 Execution of wish method with synchronized keyword without
Thread:

package demoThread;

public class Display {

public synchronized void wish(String name) {


for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

}
public static void main(String[] args) {
Display d = new Display();
d.wish("dhoni");
}
}
Output:

Good Morning:dhoni
Good Morning:dhoni
Good Morning:dhoni
Good Morning:dhoni
Good Morning:dhoni

 Execution of wish method without synchronized keyword with one


Thread got lock of given object:

package demoThread;

public class Display {

public void wish(String name) {


for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

package demoThread;

public class MyThread extends Thread {

Display d;
String name;

public MyThread(Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo{

public static void main(String[] args) {


Display d = new Display();
MyThread t = new MyThread(d, "Dhoni");
t.start();

}
}

Output:

Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni

 Execution of wish method without synchronized keyword with


multiple Thread got lock of same object:

package demoThread;

public class synchronizedDemo{

public static void main(String[] args) {


Display d = new Display();
MyThread t1 = new MyThread(d, "Dhoni");
MyThread t2 = new MyThread(d, "Yuvraj");
MyThread t3 = new MyThread(d, "Kohli");

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

}
}

Output:
Good Morning:Good Morning:Good Morning:Kohli
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:Kohli
Good Morning:Dhoni
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:Kohli
Good Morning:Yuvraj
Good Morning:Dhoni
Yuvraj
Kohli
Good Morning:Good Morning:Good Morning:Dhoni
Yuvraj
Kohli

 Execution of wish method with synchronized keyword with multiple


Thread got lock of same object:

package demoThread;

public class Display {

public synchronized void wish(String name) {


for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

package demoThread;

public class MyThread extends Thread {

Display d;
String name;

public MyThread(Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo{

public static void main(String[] args) {


Display d = new Display();
MyThread t1 = new MyThread(d, "Dhoni");
MyThread t2 = new MyThread(d, "Yuvraj");
MyThread t3 = new MyThread(d, "Kohli");
t1.start();
t2.start();
t3.start();

}
}

Output:

Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Dhoni
Good Morning:Kohli
Good Morning:Kohli
Good Morning:Kohli
Good Morning:Kohli
Good Morning:Kohli
Good Morning:Yuvraj
Good Morning:Yuvraj
Good Morning:Yuvraj
Good Morning:Yuvraj
Good Morning:Yuvraj

 If we are not declaring wish() method as synchronized then all


Threads will be executed simultaneously and hence we will get
irregular output.
 If we declare wish() method as synchronized then only one Thread
is allowed to execute wish() method and given display object.
Hence we will get regular output.

 Execution of wish method with synchronized keyword without Thread


but different object:

package demoThread;

public class Display {

public synchronized void wish(String name) {


for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

}
public static void main(String[] args) {
Display d1 = new Display();
d1.wish("dhoni");
Display d2 = new Display();
d2.wish("Yuvraj");
Display d3 = new Display();
d3.wish("kohli");

}
}
Output:

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:kohli
Good Morning:kohli
Good Morning:kohli
Good Morning:kohli
Good Morning:kohli

 Execution of wish method with synchronized keyword with multiple


Thread got lock of different object:

package demoThread;

public class Display {


public synchronized void wish(String name) {
for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

}
package demoThread;

public class MyThread extends Thread {

Display d;
String name;

public MyThread(Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo{

public static void main(String[] args) {


Display d1 = new Display();
Display d2 = new Display();
Display d3 = new Display();
MyThread t1 = new MyThread(d1, "Dhoni");
MyThread t2 = new MyThread(d2, "Yuvraj");
MyThread t3 = new MyThread(d3, "kohli");

t1.start();
t2.start();
t3.start();
}
}

Output:

Good Morning:Good Morning:Good Morning:kohli


Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:kohli
Dhoni
Yuvraj
Good Morning:Good Morning:Good Morning:kohli
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:kohli
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:kohli
Yuvraj
Dhoni

 Execution of wish method without synchronized keyword with


multiple Thread got lock of different object:

package demoThread;

public class Display {

public void wish(String name) {


for(int i = 0; i < 5; i++) {
System.out.print("Good Morning:");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println(name);
}

package demoThread;

public class MyThread extends Thread {

Display d;
String name;

public MyThread(Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo {

public static void main(String[] args) {


Display d1 = new Display();
Display d2 = new Display();
Display d3 = new Display();

MyThread t1 = new MyThread(d1, "Dhoni");


MyThread t2 = new MyThread(d2, "Yuvraj");
MyThread t3 = new MyThread(d3, "kohli");
t1.start();
t2.start();
t3.start();
}
}

Output:
Good Morning:Good Morning:Good Morning:kohli
Good Morning:Dhoni
Good Morning:Yuvraj
Good Morning:kohli
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:kohli
Good Morning:Dhoni
Good Morning:Yuvraj
Good Morning:Dhoni
Good Morning:Yuvraj
Good Morning:kohli
Good Morning:kohli
Dhoni
Yuvraj

Even wish() method is synchronized we will get irregular output


because Threads are operating on different java objects.

Conclusion:

1. If multiple Threads are operating on same java object then


synchronization is required.
2. If multiple Threads are operating on multiple java objects then
synchronization is not required.

Class level lock:

1. Every class in java has a unique lock which is also known as


class level lock.
2. If a Thread wants to execute a static synchronized method then
Thread required class level lock.
3. Once Thread got class level lock then it is allowed to execute
any static synchronized method of that class.
4. Once method execution completes automatically Thread releases the
lock.
5. While a Thread 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 method
simultaneously.
 Normal static methods
 Synchronized instance methods
 Normal instance methods

package demoThread;

public class X {

static synchronized void m1() {

Static synchronized void m2() {

Static void m3() {

}
synchronized void m4() {

}
void m5() {

Waiting state
t2 m1() X t1—class level lock(x)

t3 m2()
m1(){ }

m3()
t4
m4() m5()

t5
t6

Example:

1. create only one object for multiple display without synchronized method
but with multiple Threads

package demoThread;

public class Display {

public void display1() {


for(int i = 0; i < 26; i++) {
System.out.print(i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}

}
public void display2() {
for(int i = 65; i < 75; i++) {
System.out.print((char)i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}

package demoThread;

public class MyThread1 extends Thread {

Display d;

MyThread1 (Display d) {
this.d = d;

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

package demoThread;

public class MyThread2 extends Thread {


Display d;

MyThread2(Display d) {
this.d = d;
}

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

package demoThread;

public class synchronizedDemo {

public static void main(String[] args) {


Display d = new Display();
MyThread1 t1 = new MyThread1(d);
MyThread2 t2 = new MyThread2(d);
t1.start();
t2.start();
}
}
Output:

0AB1C2D3E4F5G6H7I8J910111213141516171819202122232425

1. create only one object for multiple display with


synchronized method but with multiple Threads

package demoThread;

public class Display {

public synchronized void display1() {


for(int i = 0; i < 26; i++) {
System.out.print(i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}

}
public synchronized void display2() {
for(int i = 65; i < 75; i++) {
System.out.print((char)i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}

package demoThread;

public class MyThread1 extends Thread {

Display d;

MyThread1 (Display d) {
this.d = d;

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

package demoThread;

public class MyThread2 extends Thread {


Display d;

MyThread2(Display d) {
this.d = d;
}

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

package demoThread;

public class synchronizedDemo {

public static void main(String[] args) {


Display d = new Display();
MyThread1 t1 = new MyThread1(d);
MyThread2 t2 = new MyThread2(d);
t1.start();
t2.start();
}
}
Output:

012345678910111213141516171819202122232425ABCDEFGHIJ

Synchronized block:
1. If very few lines of the code required synchronization then
it is not recommended to declare entire method as
synchronized. We have to enclose those few lines of the
code by using synchronized block.
2. The main advantage of the synchronized block over
synchronized method is, it reduced waiting time of Threads
and improves performance of the system/application.
3. We can declare synchronized block as follows:
2. To get lock of current object:
Synchronized(this){

If a Thread got lock of current object then only it is


allowed to execute this area.
}
3. To get lock of particular object:

Synchronized(b){

If a Thread got lock of a particular object then only it is


allowed to execute this area.
}

4. To get lock of class level:

Synchronized(Display.class){

If a Thread got class level lock of a ‘Display’ class then


only it is allowed to execute this area.
}

5. Create only one display object with multiple thread at


lock of one object.

package demoThread;

public class Display {

public void wish(String name) {


// 1 lacs coding lines
synchronized(this) {
for(int i = 0; i < 5; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {

}
System.out.println(name);
}
// 1 lacs coding lines
}

package demoThread;

public class MyThread extends Thread {

Display d;
String name;

MyThread (Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo {


public static void main(String[] args) {
Display d = new Display();
MyThread t1 = new MyThread(d, "Dhoni");
MyThread t2 = new MyThread(d, "Yuvraj");
t1.start();
t2.start();
}
}

Output:

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

6. Create multiple display object with multiple thread at


lock of different object.

package demoThread;

public class synchronizedDemo {

public static void main(String[] args) {


Display d1 = new Display();
Display d2 = new Display();
MyThread t1 = new MyThread(d1, "Dhoni");
MyThread t2 = new MyThread(d2, "Yuvraj");
t1.start();
t2.start();
}
}

Output:

Good Morning: Good Morning: Dhoni


Yuvraj
Good Morning: Good Morning: Yuvraj
Good Morning: Dhoni
Good Morning: Dhoni
Yuvraj
Good Morning: Good Morning: Dhoni
Good Morning: Yuvraj
Good Morning: Yuvraj
Dhoni

7. Create multiple display object with multiple thread at


class level lock.

package demoThread;

public class Display {

public void wish(String name) {


// 1 lacs coding lines

synchronized(Display.class) {
for(int i = 0; i < 5; i++) {
System.out.print("Good Morning: ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {

}
System.out.println(name);
}
// 1 lacs coding lines
}

package demoThread;

public class MyThread extends Thread {

Display d;
String name;

MyThread (Display d, String name) {


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

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

package demoThread;

public class synchronizedDemo {

public static void main(String[] args) {


Display d1 = new Display();
Display d2 = new Display();
MyThread t1 = new MyThread(d1, "Dhoni");
MyThread t2 = new MyThread(d2, "Yuvraj");
t1.start();
t2.start();
}
}

Output:

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

Note:
Lock concept applicable for object types and class types but not for
primitives. Hence we can’t pass primitive type as argument to
synchronized block, otherwise we will get compile time error saying
unexpected type found int required references.

FAQs:

1. What is synchronized keyword? Where we can apply?


2. Explain advantages of synchronized keyword.
3. Explain disadvantages of synchronized keyword.
4. What is race condition?
If multiple Threads are operating simultaneously on same java
object then there may be a chance of data inconsistency problem.
This is called race condition. We can overcome this problem by
using synchronized keyword.

5. What is object lock and when it is required?


6. What is class level lock and when it is required?
7. What is the difference between class level lock and object level
lock?
8. While a Thread executing synchronized method on the given object,
is the remaining Threads are allowed to execute any other
synchronized method simultaneously on the same object.
No
9. What is synchronized block?
10. How to declare synchronized block to get lock of current
object.
11. How to declare synchronized block to get lock of class
level.
12. What is the advantage of synchronized block over
synchronized method?
13. Is a thread can acquired multiple locks simultaneously?
Yes, from different objects.

package demoThread;

public class X {

public synchronized void m1() {


// here thread has lock of X object

Y y = new Y();

synchronized (y) {
// here thread has lock of X and Y object

Z z = new Z();

synchronized (z) {
// here thread has lock of X,Y and Z object

}
}

What is synchronized statement (interview people created


terminology)?

The statements present in synchronized method and synchronized


block are called synchronized statements.

Inter Thread communication:


1. Two Threads can communicate with each other by using wait(),
notify() and notifyAll() methods.

2. The thread which is expecting updation is responsible to


call wait() method then immediately the Thread will enterd
into waiting state.

3. The Thread which is responsible to perform updation. After


performing updation it is responsible to call notify()
method then waiting Thread will get notification and
continue its execution with those updated items.
4. Wait(), notify(), notifyAll() method present in object class
but not in Thread class because Thread can call these
methods on any java object.
5. To call wait() , notify() or notifyAll() methods on any
object, Thread should be owner of that object i.e the Thread
should has lock of that object i.e the Thread should be
inside synchronized area.
6. Hence we can call wait(), notify() and notifyAll() methods
only from synchronized area. Otherwise we will get
RunTimeException saying IllegalMonitorStateException.
7. If a Thread calls wait() method on any object, it
immediately releases the lock of that particular object and
entered into waiting state.
8. If a Thread calls notify() method on any object it releases
the lock of that object but may not immediately.
9. Except wait(), notify(), notifyAll() there is no other
method where Thread releases the lock.

Method Is Thread releases the lock?


1. Yield() No
2. Join() No
3. Sleep() No
4. Wait() Yes
5. Notify() Yes
6. notifyAll() Yes

 Public final void wait throws InterruptedException ()

 Public final native void wait throws InterruptedException


(long ms)

 Public final void wait throws InterruptedException (long ms,


int ns)

Every wait() method throws InterruptedException which is checked


exception. Hence whenever we are using wait() method compulsory
we should handle this InterruptedException either by try-catch or
by throws keyword. Otherwise we will get compile time error.

 Public final native void notify()


 Public final native void notifyAll()
package demoThread;

public class ThreadB extends Thread {


int total = 0;
@Override
public void run() {
synchronized (this) {
System.out.println("child thread starts
calculation");
for(int i = 0; i <= 100; i++) {
total = total+i;
}
System.out.println("child giving notification
call");
this.notify();
}

}
}
package demoThread;

public class ThreadA {

public static void main(String[] args) throws InterruptedException {


ThreadB b = new ThreadB();
b.start();
synchronized (b) {
System.out.println("main thread calling wait method");
b.wait();
System.out.println("main thread got notification call");
System.out.println(b.total);
}

// Thread.sleep(1);
// for(int i = 0; i < 10; i++) {
// System.out.println(b.total);
// }
}
}
Output:

main thread calling main method


child thread starts calculation
child giving notification call
main thread got notification call
5050

 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
entered 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.

Producer Thread Consumer Thread

Queue
package demoThread;

public class Consumer {

public void consumer(int q) {


synchronized(q) {
if("queue is empty" + q==0) {
q.wait();
} else {
System.out.println("consume items");
}
}
}

package demoThread;

public class Producer {

public void producer() {


synchronized (q) {
System.out.println("produced items to the queue");
q.notify();
}
}

 We can use notify() method to give notification for only


one waiting Thread.
 If multiple Threads are waiting then only one Thread will
be notified and remaining Threads have to wait for further
notifications.
 Which Thread will be notified we can’t expect it depends on
JVM.
 We can use notifyAll() method to give the notification for
all waiting Threads of a particular object.
 Even though multiple Threads notified but execution will be
performed one by one because Threads required only one lock
available.
 On which object we are calling wait method Thread required
the lock of that particular object.
Example:

If we are calling wait() method on s1 then we have to get lock of s1 object,


but not s2 object.

 Synchronized(s1){

S2.wait();

}----wrong
 Synchronized(s1){

S1.wait();

}----------right

Deadlock:
1. If two Threads are waiting for each other forever. Such type of
infinite waiting is called 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 demoThread;

class A {
public synchronized void foo(B b) {
System.out.println("Thread1 starts execution of foo() method");
try{
Thread.sleep(2000);
}
catch (InterruptedException e)
{}
System.out.println("Thread1 trying to call b.last()");
b.last();
}

public synchronized void last() {


System.out.println("inside A, this is last()method");
}
}
class B {
public synchronized void bar(A a) {
System.out.println("Thread2 starts execution of bar()
method");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("Thread2 trying to call a.last()");
a.last();
}

public synchronized void last() {


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

public class DeadLock implements Runnable {


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

DeadLock() {
Thread t = new Thread(this);
t.start();
a.foo(b);// main thread
}

public void run() {


b.bar(a);// child thread
}

public static void main(String[] args) {


new DeadLock();// main thread
}
}

Output:

Thread1 starts execution of foo() method

Thread2 starts execution of bar() method

Thread2 trying to call a.last()


Thread1 trying to call b.last()

//here cursor always waiting.

Note: If we remove atleast one syncronized keywoed then we won't get

DeadLOck.Hence syncronized keyword in the only reason for DeadLock due to


this while using syncronized keyword we have to handling carefully.

Daemon Threads:

The Threads which are executing in the background are called daemon Threads.

The main objective of daemon Threads is to provide support for non-daemon


Threads like main Thread.

Example:

Garbage collector

 Whenever the program runs with low memory the JVM will execute Garbage
Collector to provide free memory. So that the main Thread can continue
it's execution.
 We can check whether the Thread is daemon or not by using isDaemon()
method of Thread class.

public final boolean isDaemon();

 We can change daemon nature of a Thread by using setDaemon () method.

public final void setDaemon(boolean b);

 But we can change daemon nature before starting Thread only. That is
after starting the Thread if we are trying to change the daemon nature
we will get R.E saying IllegalThreadStateException.
 Default Nature : Main Thread is always non daemon and we can't change
its daemon nature because it's already started at the beginning only.
 Main Thread is always non daemon and for the remaining Threads daemon
nature will be inheriting from parent to child that is if the parent is
daemon child is also daemon and if the parent is non daemon then child
is also non daemon.
 Whenever the last non daemon Thread terminates automatically all daemon
Threads will be terminated.
Example:

class MyThread extends Thread {

Public class DaemonThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().isDaemon());

MyThread t=new MyThread();

System.out.println(t.isDaemon());----------1

t.start();

t.setDaemon(true);

System.out.println(t.isDaemon());

Output:

false

false

RE:IllegalThreadStateException

Example:

class MyThread extends Thread

package demoThread;

class MyThread extends Thread {


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

public class DaemonThreadDemo {


public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // -->1
t.start();
System.out.println("end of main Thread");
}
}

Output:

End of main Thread

 If we comment line 1 then both main & child Threads are non-Daemon ,
and hence both threads will be executed untill there completion.
 If we are not comment line 1 then main thread is non-Daemon and child
thread is Daemon. Hence when ever main Thread terminates automatically
child thread will be terminated.

Lazy thread

 If we are commenting line 1 then both main and child Threads are non
daemon and hence both will be executed until they completion.
 If we are not commenting line 1 then main Thread is non daemon and
child Thread is daemon and hence whenever main Thread terminates
automatically child Thread will be terminated.

Deadlock vs Starvation:

 A long waiting of a Thread which never ends is called deadlock.


 A long waiting of a Thread which ends at certain point is called
starvation.
 A low priority Thread has to wait until completing all high priority
Threads.
 This long waiting of Thread which ends at certain point is called
starvation.
How to kill a Thread in the middle of the line?

 We can call stop() method to stop a Thread in the middle then it will
be entered into dead state immediately.

public final void stop();

 stop() method has been deprecated and hence not recommended to use.

suspend and resume methods:

 A Thread can suspend another Thread by using suspend() method then that

Thread will be paused temporarily.

 A Thread can resume a suspended Thread by using resume() method then


suspended Thread will continue its execution.

1. public final void suspend();

2. public final void resume();

 Both methods are deprecated and not recommended to use.

RACE condition:

 Executing multiple Threads simultaneously and causing data


inconsistency problems is nothing but Race condition
 we can resolve race condition by using synchronized keyword.

ThreadGroup:

 Based on functionality we can group threads as a single unit which is


nothing but ThreadGroup.
 ThreadGroup provides a convenient way to perform common operations for
all threads belongs to a perticular group.
 We can create a ThreadGroup by using the following constructors

ThreadGroup g=new ThreadGroup(String gName);


 We can attach a Thread to the ThreadGroup by using the following
constructor of Thread class

Thread t=new Thread(ThreadGroup g, String name);

ThreadGroup g=new ThreadGroup("Printing Threads");

MyThread t1=new MyThread(g,"Header Printing");

MyThread t2=new MyThread(g,"Footer Printing");

MyThread t3=new MyThread(g,"Body Printing");

-----------

g.stop();

ThreadLocal(1.2 v):

 We can use ThreadLocal to define local resources which are required for
a perticular Thread like DBConnections, counterVariables etc.
 We can use ThreadLocal to define Thread scope like Servlet
Scopes(page,request,session,application).

GreenThread:
 Java multiThreading concept is implementing by using the
following 2 methods :
1. GreenThread Model
2. Native OS Model

GreenThread Model
 The threads which are managed completely by JVM without taking
support for underlying OS, such type of threads are called Green
Threads.
Native OS Model
 The Threads which are managed with the help of underlying OS are
called Native Threads.
 Windows based OS provide support for Native OS Model
 Very few OS like SunSolaries provide support for GreenThread
Model
 Anyway GreenThread model is deprecated and not recommended to
use.
Life cycle of a Thread:

What is the difference between extends Thread and implements Runnable?

1. Extends Thread is useful to override the public void run() method of


Thread

class.

2. Implements Runnable is useful to implement public void run() method of

Runnable interface.

Extends Thread, implements Runnable which one is advantage?

If we extend Thread class, there is no scope to extend another class.

Example:

Class MyClass extends Frame,Thread//invalid

If we write implements Runnable still there is a scope to extend one more


class.

Example:

1. class MyClass extends Thread implements Runnable


2. class MyClass extends Frame implements Runnable

How can you stop a Thread which is running?

Step 1: Declare a boolean type variable and store false in that variable.

boolean stop=false;

Step 2: If the variable becomes true return from the run() method.

If(stop) return;

Step 3: Whenever to stop the Thread store true into the variable.

System.in.read();//press enter

Obj.stop=true;

You might also like