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

Module - IV Java

The document provides an overview of multithreading in Java, explaining the concepts of threads, processes, and multitasking. It details the life cycle of a thread, including states such as new, runnable, running, blocked, and dead, as well as the creation of threads through extending the Thread class or implementing the Runnable interface. Additionally, it discusses the main thread, daemon threads, and provides examples of thread creation and execution in Java.

Uploaded by

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

Module - IV Java

The document provides an overview of multithreading in Java, explaining the concepts of threads, processes, and multitasking. It details the life cycle of a thread, including states such as new, runnable, running, blocked, and dead, as well as the creation of threads through extending the Thread class or implementing the Runnable interface. Additionally, it discusses the main thread, daemon threads, and provides examples of thread creation and execution in Java.

Uploaded by

Shashank S
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 119

Module- IV

Multi Threading

Prepared by Ms. J Karthiyayini J


Thread Concept
• The thread in Java simply represents a single
independent path of execution of a group of statements.
It is the flow of execution, from beginning to end, of a
task.
• When we write a group of statements in a program,
these statements are executed by JVM one by one. This
execution process is called thread in Java.
• There is always at least one thread running internally in
every program and this thread is used by JVM to execute
statements in the program.
• When a program contains a single flow of control, it is
called single-threaded program. In a single thread
program, there is a beginning, a body, and an end, and
execute commands sequentially.
When we create more than one thread in a program, each thread has its own
path of execution and all the threads share the same memory address space,
data, and code in a program.
What is Process in Java?
• Thread in Java is the smallest unit of executable code in a
program. It helps to divide a program into multiple parts
to speed up the process.
• A process is a program that executes as a single thread.
In other words, when an executable program is loaded
into memory, it is called process.
• Every individual process has its own separate memory
address space and can execute a different program.
• Each process can have more than one thread.
• Each process communicates through the operating
system, files, and network.
• When we will create a new thread in a program, it shares
the same memory address space with other threads in a
program whereas every individual process has its own
separate memory address space.
The thread is executed inside a process and one process can have also
multiple threads. There can be multiple processes inside the operating
system.
Multiple Threads are independent of each other. At a time only one
thread is executed. If an exception occurs in one thread, it doesn’t
affect other threads.
Multitasking
• Multitasking is a process of performing multiple tasks
simultaneously. We can understand it by computer system that
perform multiple tasks like: writing data to a file, playing music,
downloading file from remote server at the same time.
• Multitasking can be achieved either by using multiprocessing or
multithreading. Multitasking by using multiprocessing involves
multiple processes to execute multiple tasks simultaneously whereas
Multithreading involves multiple threads to executes multiple tasks.
• Why Multithreading ?
Thread has many advantages over the process to perform
multitasking. Process is heavy weight, takes more memory and
occupy CPU for longer time that may lead to performance issue with
the system. To overcome these issue process is broken into small unit
of independent sub-process. These sub-process are called threads
that can perform independent task efficiently. So nowadays
computer systems prefer to use thread over the process and use
multithreading to perform multitasking.
Why Java threads are lightweight
process?
• Java Threads are also known as lightweight threads or light-
weight processes.
• It means that they can be executed in the same memory
space because all the threads in the main application program
share the same address space in the memory so that they can
easily communicate among themselves.
• Thus, they also take less space in memory and less processor
time.
Java Thread Model
• A thread is a subpart of a process that can run
individually.
• In java, a thread goes through different states
throughout its execution. These stages are
called thread life cycle states or phases.
• A thread may in any of the states like new,
ready or runnable, running, blocked or wait,
and dead or terminated state.
1. New (Newborn State): When we create a thread object using Thread class,
thread is born and is known to be in Newborn state. That is, when a thread is born,
it enters into new state but the start() method has not been called yet on the
instance.
In other words, Thread object exists but it cannot execute any statement because it is
not an execution of thread. Only start() method can be called on a new thread;
otherwise, an IllegalThreadStateException will be thrown.
2. Runnable state:
• Runnable state means a thread is ready for execution. When
the start() method is called on a new thread, thread enters
into a runnable state.
• In runnable state, thread is ready for execution and is waiting
for availability of the processor (CPU time). That is, thread has
joined queue (line) of threads that are waiting for execution.
• If all threads have equal priority, CPU allocates time slots for
thread execution on the basis of first-come, first-serve
manner. The process of allocating time to threads is known
as time slicing. A thread can come into runnable state from
running, waiting, or new states.
3. Running state:
• Running means Processor (CPU) has allocated time slot to
thread for its execution. When thread scheduler selects a
thread from the runnable state for execution, it goes into
running state.
• In running state, processor gives its time to the thread for
execution and executes its run method. This is the state
where thread performs its actual functions. A thread can
come into running state only from runnable state.
• A running thread may give up its control in any one of the
following situations and can enter into the blocked state.
1. When sleep() method is invoked on a thread to sleep for
specified time period, the thread is out of queue during this
time period. The thread again reenters into the runnable state
as soon as this time period is elapsed.
2. When a thread is suspended using suspend() method for some
time in order to satisfy some conditions. A suspended thread
can be revived by using resume() method.
3. When wait() method is called on a thread to wait for some
time. The thread in wait state can be run again using notify()
or notifyAll() method.
4. Blocked state: A thread is considered to be in the blocked
state when it is suspended, sleeping, or waiting for some time
in order to satisfy some condition.
• When a thread is in the blocked or waiting state, it may move
to Runnable state due to reasons like sleep time completed,
waiting time completed, notify( ) or notifyAll( ) method called,
resume( ) method called, etc.
Example
Thread.sleep(1000);
wait(1000);
wait();
suspened();
notify();
notifyAll();
resume();
5. Dead state: A thread dies or moves into dead state automatically
when its run() method completes the execution of statements. That
is, a thread is terminated or dead when a thread comes out of run()
method. A thread can also be dead when the stop() method is
called.
Note:
• During the life cycle of thread in Java, a thread moves from one
state to another state in a variety of ways. This is because in
multithreading environment, when multiple threads are executing,
only one thread can use CPU at a time.
• All other threads live in some other states, either waiting for their
turn on CPU or waiting for satisfying some conditions. Therefore, a
thread is always in any of the five states.
Main Thread/method in Java
• Every Java program has always at least one thread, even if we
do not create any thread. This thread is called main thread.
• The main thread is also called parent thread and the rest of
threads that are generated from it are called child threads of
the program.
• Main thread is the last thread to be executed in a program.
When main thread finishes the execution, the program
terminates immediately.
• Whenever Java program starts, main thread is created
automatically.
• This main thread is available in all programs. We can control
the execution of the main thread by creating a Thread object
and then using methods of Thread class.
• A Thread object can be created as follows:
Thread obj = Thread.currentThread();
• Since currentThread() method of class Thread is a public
static method, therefore, we can call it using class name.
• The currentThread() method returns a reference of
current thread on which it is called. “obj” is a reference
variable that is assigned to store the return value of
currentThread() method.
• Two important things to know about main thread are,
1. It is the thread from which other threads will be
produced.
2. It must be always the last thread to finish execution.
Relation between the main() method and main thread in Java
For each program, a Main thread is created by JVM (Java Virtual Machine). The
“Main” thread first verifies the existence of the main() method, and then it
initializes the class. Note that from JDK 6, main() method is mandatory in a
standalone java application.
Example-1
public class MainThread
{
public static void main(String[] args)
{
// Create a Thread object by calling
//currentThread() method of class Thread.
Thread obj = Thread.currentThread();
System.out.println("Current thread is " +obj);
System.out.println("Name of current thread is "
+obj.getName()); }
Output:
Current thread is Thread[main,5,main]
Name of current thread is main
Explanation
1. In this program, currentThread() is a static method in a class Thread.
Therefore, we called it as Thread.currentThread(). This method returns the
reference of main thread because this is called inside the main thread. The
reference of main thread will be stored in a variable obj of type Thread.
2. When line 8 will be executed by JVM, it will display an output
“Thread[main,5,main]” on screen. In the square bracket, the first value,
main represents the name of thread; second value 5 represents the
priority of main thread.
Every thread will have a priority number associated with it that can be range
from 1 to 10. 1 is the minimum priority and 10 is the maximum priority of
a thread.
The third value main represents the name of group to which main thread
belongs.
3. getName() method of Thread class returns the name of thread that is
referred by object obj.
Constructors of Thread class
• The various constructors of thread class are
defined in java.lang package that can be used to
create an object of thread are as follows:
1. Thread(): This is a basic and default constructor
without parameters. It simply creates an object of
Thread class.
2. Thread(String name): It creates a new thread
object with specified name to a thread.
3. Thread(Runnable r): It creates a thread object by
passing a parameter r as a reference to an object
of the class that implements Runnable interface.
Daemon Thread

• Daemon threads is a low priority thread that provide


supports to user threads.
• These threads can be user defined and system defined as
well.
• Garbage collection thread is one of the system generated
daemon thread that runs in background.
• These threads run in the background to perform tasks such
as garbage collection.
• Daemon thread does allow JVM from existing until all the
threads finish their execution.
• When a JVM founds daemon threads it terminates the
thread and then shutdown itself, it does not care Daemon
thread whether it is running or not.
Example- Daemon thread
public class DaemonDemo1 extends Thread
{
public DaemonDemo1(String name1)
{ super(name1);
}
public void run()
{ if(Thread.currentThread().isDaemon())
{ System.out.println(getName() + " is Daemon thread"); }
else { System.out.println(getName() + " is User thread"); } }
public static void main(String[] args)
{ DaemonDemo1 D1 = new DaemonDemo1("D1");
DaemonDemo1 D2 = new DaemonDemo1("D2");
DaemonDemo1 D3 = new DaemonDemo1("D3");
D1.setDaemon(true);
D1.start();
D2.start();
D3.setDaemon(true);
D3.start(); } }
Creating Threads
• Every Java program has at least one thread called main
thread. When a program starts, main thread starts
running immediately.
• Apart from this main thread, we can also create our own
threads in a program that is called child thread. Every child
threads create from its main thread known as parent
thread.
• There are two ways to create a new thread in Java. They
are as follows:
1. One is by extending java.lang.Thread class
2. Another is by implementing java.lang.Runnable
interface
• Extending Thread class is the easiest way to create a new
thread in Java. The following steps can be followed to create
your own thread in Java.
1. Create a class that extends the Thread class. In order to
extend a thread, we will use a keyword extends. The Thread
class is found in java.lang package.
The syntax for creating a new class that extends Thread class
is as follows:
Class Myclass extends Thread
2. Now in this newly created class, define a method run(). Here,
run() method acts as entry point of the new thread. The run()
method contains the actual task that thread will perform.
Thus, we override run() method of Thread class.
public void run()
{
// statements to be executed. }
3. Create an object of newly created class so that run() method is
available for execution. The syntax to create an object of Myclass is
as follows:
Myclass obj = new Myclass();
4. Now create an object of Thread class and pass the object reference
variable created to the constructor of Thread class.
Thread t = new Thread(obj);
or
Thread t = new Thread(obj, "threadname");
5. Run the thread. For this, we need to call to start() method of Thread
class because we cannot call run() method directly. The syntax to
call start() method is as follows:
t.start();
Now, the thread will start execution on the object of Myclass, and
statements inside run() method will be executed while calling it.
Example-2
class SampleThread extends Thread
{
public void run()
{
System.out.println("Thread is under Running...");
for(int i= 1; i<=10; i++)
{
System.out.println("i = " + i);
}
}
}
public class My_Thread_Test
{
public static void main(String[] args)
{
SampleThread t1 = new SampleThread();
System.out.println("Thread about to start...");
t1.start();
}
}
Example-3
public class Main extends Thread
{
public static void main(String[] args)
{
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run()
{ System.out.println("This code is running in a thread");
}
}
Example-4
class MyThread extends Thread
{
public static void main(String[] args)
{
MyThread thread = new MyThread();
System.out.println("Created thread by extending Thread");
thread.start();
}
public void run()
{
System.out.println("Thread running...");
}
}
Creating Threads in Java using Runnable
Interface
• Threads can also be created by implementing Runnable
interface of java.lang package. Creating a thread by
implementing Runnable interface is very similar to creating a
thread by extending Thread class.
• All steps are similar for creating a thread by implementing
Runnable interface except the first step. The first step is as
follows:
1. To create a new thread using this method, create a class
that implements Runnable interface of java.lang package. The
syntax for creating a new class that implements Runnable
interface is as follows:
class Myclass implements Runnable
Example-5
public class Main implements Runnable
{
public static void main(String[] args)
{
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run()
{
System.out.println("This code is running in a thread");
}}
Example-6
public class MyThread implements Runnable
{
public void run()
{
System.out.println("New thread running ");
for(int i = 1; i <= 5; i++)
{
System.out.println(i);
}
System.out.println(Thread.currentThread());
}
public static void main(String[] args)
{
System.out.println("Main thread running");
// Create an object of MyThread class.
MyThread th = new MyThread();
// Create an object of Thread class and pass reference
// variable th to Thread class constructor.
Thread t = new Thread(th);
t.start(); // This thread will execute statements inside
//run() method of MyThread object.
}
}
Output:
Main thread running
New thread running
1
2
3
4
5
Thread[Thread-0,5,main]
Explanation:
• When the start() method of Thread class is
called using reference variable t, the thread
will start execution on the object of
MyThread. In that object, start() method calls
run() method and executes statements inside
the run() method. Whenever the execution of
run() method stops, execution of thread also
stops.
Multitasking with single Thread in
Java
• In all the previous example programs, we have noticed
that one thread executes only one task at a time. But
we can also execute multiple tasks from a single
thread.
• For example, suppose there are three tasks to be
executed in a program. For this purpose, we will create
a thread and pass 3 tasks one by one to the thread.
• We will write code separately in separate methods
such as task1, task2, and task3 for all these tasks. Then,
all these methods will call from run() method one by
one.
Example-7
public class MyThread implements Runnable
{
int a = 20, b = 10;
public void run()
{ addition(); // task1
subtraction(); // task2
multiplication(); // task3
}
void addition()
{
int sum = a + b;
System.out.println("Addition of two numbers: " +sum);
}
void subtraction()
{
int sub = a - b;
System.out.println("Subtraction of two numbers: " +sub); }
void multiplication()
{
int multiply = a * b;
System.out.println("Multiplication of two numbers: " +multiply); }
public static void main(String[] args)
{ System.out.println("Main thread running");
MyThread th = new MyThread();
Thread t = new Thread(th);
t.start();
}}
• In this example program, a single thread t is
used to execute three tasks one by one.
• Note that at a time, a thread executes only
one method inside the run() method. It can
never execute other methods unless they are
called from run() method.
Keypoints
• Extending Thread class and implementing Runnable interface
for creating threads in Java are functionally same. But there is one
disadvantage of creating threads in Java using extending Thread
class.
• When you extend Thread class, there is no scope to extend another
class because multiple inheritance is not supported by Java.
For example, class Myclass extends Thread, AnotherClass // Invalid
• But if you implement Runnable interface for creating a thread, still
there is scope to extend another class. So, implementing Runnable
interface for creating a new thread has an advantage for
programmers.
• In Java, the word thread means two different things.
1. An instance of Thread class.
2. or, A thread of execution.
• An instance of Thread class is just an object, like any other object in
java. But a thread of execution means an individual "lightweight"
process that has its own call stack. In java each thread has its own
call stack.
Creating Multiple Threads in Java

• In the previous all thread programs, we have used only two


threads: main thread, and one new thread (known as child
thread).
• Basically, when we need to perform several tasks at a time,
we can create multiple threads to perform multiple tasks in a
program.
• For example, to perform two tasks, we can create two threads
and attach them to two tasks. Hence, creating multiple
threads in Java programming helps to perform more than one
task simultaneously.
• Creating more than one thread to perform multiple tasks is
called multithreading in Java. In multiple threading
programming, multiple threads are executing simultaneously
that improves the performance of CPU because CPU is not
idle if other threads are waiting to get some resources.
• Multiple threads share the same address space in the heap
memory. Therefore, It is good to create multiple threads to
execute multiple tasks rather than creating multiple
processes. Look at the below picture.
Example-8
// Two threads performing two tasks at a time.
public class MyThread extends Thread
{ // Declare a String variable to represent task.
String task;
MyThread(String task)
{
this.task = task;
}
public void run()
{
for(int i = 1; i <= 5; i++)
{
System.out.println(task+ " : " +i);
try { Thread.sleep(1000);
// Pause the thread execution for 1000 milliseconds.
}
catch(InterruptedException ie)
{ System.out.println(ie.getMessage());
}
} // end of for loop.
} // end of run() method.
public static void main(String[] args)
{ // Create two objects to represent two tasks.
MyThread th1 = new MyThread("Cut the ticket");
// Passing task as an argument to its constructor.
MyThread th2 = new MyThread("Show your seat number");
// Create two objects of Thread class and pass two objects as
//parameter to constructor of Thread class.
Thread t1 = new Thread(th1);
Thread t2 = new Thread(th2);
t1.start();
t2.start();
}}
• Output:
Cut the ticket : 1
Show your seat number : 1
Show your seat number : 2
Cut the ticket : 2
Show your seat number : 3
Cut the ticket : 3
Show your seat number : 4
Cut the ticket :
4 Show your seat number : 5
Cut the ticket : 5
Explanation:
1. In the preceding example program, we have created two
threads on two objects of MyThread class. Here, we created
two objects to represent two tasks.
When we will run the above program, the main thread starts
running immediately. Two threads will generate from the
main thread that will perform two different tasks.
2. When t1.start(); is executed by JVM, it starts execution of code
inside run() method and print the statement “Cut the ticket”
on the console.
3. When JVM executes Thread.sleep(1000); inside the try block,
it pauses the thread execution for 1000 milliseconds. Here.
sleep() method is a static method that is used to pauses the
execution of thread for a specified amount of time.
For example, Thread.sleep(1000); will pause the execution of
thread for 1000 milliseconds (1 sec). 1000 milliseconds means
1 second. Since sleep() method can throw an exception
named InterruptedException, we will catch it into catch block.
4. Meanwhile, JVM executes t2.start(); and second thread starts
execution of code inside the run() method almost
simultaneously. It will print the statement “Show your seat
number”. Now, the second thread will undergo to sleep for
1000 milliseconds.
5. When the pause time period of the first thread is elapsed, it
will reenter into running state and starts the execution of
code inside run() method. The same process will also happen
for second thread. In this manner, both threads will perform
two tasks almost simultaneously.
Note:
1. In the above output, you will notice that the program is
displaying two messages “Cut the ticket” and “Show
your seat number” in shuffled manner.
This is because the CPU shares time between two
threads. CPU executes the run() method of t1 for time
slice and prints one message.
Meanwhile, CPU control goes to execute the run()
method of t2 for next time slice and prints the second
message. This process goes on.
2. The process of allotting time slots to threads is
called time slice.
Therefore, we can say that thread behavior is
unpredictable in Java. When you will run code second
time,we may get different output.
Thread Scheduler in Java
• Thread scheduler in Java is the component of JVM that determines
the execution order of multiple threads on a single processor (CPU).
• It decides the order in which threads should run. This process is
called thread scheduling in Java.
• When a system with a single processor executes a program having
multiple threads, CPU executes only a single thread at a particular
time.
• Other threads in the program wait in Runnable state for getting the
chance of execution on CPU because at a time only one thread can
get the chance to access the CPU.
• The thread scheduler selects a thread for execution from runnable
state. But there is no guarantee that which thread from runnable
pool will be selected next to run by the thread scheduler.
• Java runtime system mainly uses one of the following two
strategies:
1. Preemptive scheduling
2. Time-sliced scheduling
Preemptive Scheduling

• This scheduling is based on priority. Therefore, this scheduling


is known as priority-based scheduling. In the priority-based
scheduling algorithm, Thread scheduler uses the priority to
decide which thread should be run.
• If a thread with a higher priority exists in Runnable state
(ready state), it will be scheduled to run immediately.
• In case more than two threads have the same priority then
CPU allocates time slots for thread execution on the basis of
first-come, first-serve manner.
Time-Sliced Scheduling

• The process of allocating time to threads is


known as time slicing in Java. Time-slicing is
based on non-priority scheduling. Under this
scheduling, every running thread is executed for a
fixed time period.
• A currently running thread goes to the Runnable
state when its time slice is elapsed and another
thread gets time slots by CPU for execution.
• With time-slicing, threads having lower priorities
or higher priorities gets the same time slots for
execution.
Thread Priorities
• In a Multi threading environment, thread scheduler assigns
processor to a thread based on priority of thread.
• Whenever we create a thread in Java, it always has some
priority assigned to it.
• Priority can either be given by JVM while creating the
thread or it can be given by programmer explicitly.
Accepted value of priority for a thread is in range of 1 to 10.
There are 3 static variables defined in Thread class for
priority.
1.public static int MIN_PRIORITY: This is minimum
priority that a thread can have. Value for this is 1.
2.public static int NORM_PRIORITY: This is default priority
of a thread if do not explicitly define it. Value for this is 5.
3.public static int MAX_PRIORITY: This is maximum
priority of a thread. Value for this is 10.
• The default priority of a thread is 5. Thread
class in Java also provides several priority
constants to define the priority of a thread.
These are:
• 1. MIN_PRIORITY = 1
2. NORM_PRIORITY = 5
3. MAX_PRIORTY = 10
• These constants are public, final, and static
members of the Thread class.
• Thread scheduler selects the thread for execution on the
first-come, first-serve basis. That is, the threads having
equal priorities share the processor time on the first-come,
first-serve basis.
• When multiple threads are ready for execution, the highest
priority thread is selected and executed by JVM. In case
when a high priority thread stops, yields, or enters into the
blocked state, a low priority thread starts executing.
• If any high priority thread enters into the runnable state, it
will preempt the currently running thread forcing it to
move to the runnable state. Note that the highest priority
thread always preempts any lower priority thread.
How to get Priority of Current Thread
in Java?
• Thread class provides a method named
getPriority() that is used to determine the
priority of a thread.
• It returns the priority of a thread through
which it is called.
Example-9
public class A implements Runnable
{
public void run()
{
System.out.println(Thread.currentThread());
}
public static void main(String[] args)
{ A a = new A();
Thread t = new Thread(a, "NewThread");
System.out.println("Priority of Thread: " +t.getPriority());
System.out.println("Name of Thread: " +t.getName());
t.start();
}
}
• Output:
Priority of Thread: 5
Name of Thread: NewThread
Thread[NewThread,5,main]
How to set Priority of Thread in Java?

• The setPriority() of Thread class is used to set the priority of a


thread. This method accepts an integer value as an argument
and sets that value as priority of a thread through which it is
called.
• Syntax:
ThreadName.setPriority(n);
where, n is an integer value which ranges from 1 to 10.
Example-10
public class A implements Runnable
{
public void run()
{ System.out.println(Thread.currentThread());
}
public static void main(String[] args)
{
A a = new A();
Thread t = new Thread(a, "NewThread");
t.setPriority(2); // Setting the priority of thread.
System.out.println("Priority of Thread: " +t.getPriority());
System.out.println("Name of Thread: " +t.getName());
t.start();
}}
Output:
Priority of Thread: 2
Name of Thread: NewThread
Thread[NewThread,2,main]
• In this example program, the setPriority() method
sets the priority of Thread t to 2.
• It has been already discussed that thread priority
plays an important role during the process of
thread scheduling. The thread scheduler chooses
that thread for execution that has the highest
priority.
Example-11
public class A implements Runnable
{ public void run()
{ System.out.println(Thread.currentThread());
}
public static void main(String[] args)
{
A a = new A();
Thread t1 = new Thread(a, "First Thread");
Thread t2 = new Thread(a, "Second Thread");
Thread t3 = new Thread(a, "Third Thread");
t1.setPriority(4);
t2.setPriority(2);
t3.setPriority(8);
t1.start();
t2.start();
t3.start();
}}
Output:
Thread[Third Thread,8,main]
Thread[First Thread,4,main]
Thread[Second Thread,2,main]
• The priority of Thread t1 is 4, t2 is 2, and t3 is 8.
Thread t3 is the highest priority as compared to
t1 and t2.
• But it is not necessary that we will get the same
priorities whenwe will run multiple times.
Example-12
class MyThread extends Thread
{
public void run()
{
System.out.println("Thread Running...");
}
public static void main(String[]args)
{
MyThread p1 = new MyThread();
p1.start();
System.out.println("max thread priority : " + p1.MAX_PRIORITY);
System.out.println("min thread priority : " + p1.MIN_PRIORITY);
System.out.println("normal thread priority : " + p1.NORM_PRIORITY);
}}
Note: Thread priorities cannot guarantee that a
higher priority thread will always be executed
first than the lower priority thread. The
selection of the threads for execution depends
upon the thread scheduler which is platform
dependent.
How to Stop Thread in Java with
Example
• A thread in Java program will terminate ( or move to dead
state) automatically when it comes out of run() method.
• But if we want to stop a thread from running or runnable
state, we will need to calling stop() method of Thread
class. The stop() method is generally used when we
desire premature death of a thread.
• The general syntax for calling stop method in java
programming is as follows:
static void stop()
• Since the stop() method is static in nature, therefore, it can
be called by using Thread class name. When the stop()
method is called on a thread, it causes the thread to move
to the dead state.
Can a thread is again alive when it goes into dead state?

No, when a thread is terminated or moves into dead state, it cannot alive again. If
we try to it by calling start() method, we will get
an IllegalThreadStateException exception.
Why is stop method deprecated in
Java?
• In the early days of Java, Thread class defined a stop() method that
simply terminates a thread. But later on Java 1.2 version, stop()
method had been deprecated. This is because this method is
“inherently unsafe” and can cause serious problem sometimes.
Therefore, it should not be used in the program for thread safety.
• An interviewer can ask you an interesting question that what logic
will you use to stop a thread in the place of stop() method because
stop() method had been deprecated from Java 1.2.
• Basically, there are two ways through which we can easily stop a
thread in java program. They are:
• 1. By using boolean variable.
2. By using isInterrupted() method
Thread.sleep() Method

• Sometimes we need to make a thread sleep for a particular period


of time. For this, we use sleep() method in Java program.
• The sleep() method is a static method provided by the Thread
class so it can be called by its class name.
• It is used to sleep a thread for a specified amount of time. It always
pauses the current thread for a given period of time.
• The sleep() method controls the behavior of thread and transition
of thread from one state to another.
• When the sleep() method is called on Thread object, the thread is
become out of the queue and enters into blocked (or non-runnable
state) for a specified amount of time.
• When the specified amount of time is elapsed, the thread does not
go into running state (execution state) immediately. It goes into the
runnable state (ready state) until it is called by Thread Scheduler of
JVM.
Syntax of sleep() method in Java:
public static void sleep(long milliseconds) throws InterruptedException
public static void sleep(long milliseconds, int nanoseconds) throws
InterruptedException
• The sleep() method can throw an exception named InterruptedException
when interrupted in a program. Therefore, using sleep() method needs
either we throw InterruptedException to the caller or the call to sleep()
method must be enclosed in Java try-catch block otherwise, the program
will not complete.
Yield Method in Java

• When a currently executing thread goes to the


runnable state from running state, this
process is called yield in Java.
• When running state receives higher priority
thread than the thread that is currently
running, thread scheduler sends the currently
running thread back to the runnable state and
selects another thread of equal or higher
priority to start its execution.
To send a running thread back to runnable state, yield() method of Thread
class is called on the current Thread object.
Since yield() method is a static method so we can call it by using its class
name like this:
Thread.yield();
In the preceding syntax, yield() method is called on the Thread object.
Calling yield() method on the Thread object pauses execution of the current
thread and selects thread of equal or higher priority to start its execution.
Example-13
public class A implements Runnable
{ public void run()
{
System.out.println(Thread.currentThread());
Thread.yield(); // Calling yield() method on current thread to
//move back into the runnable state from running state.
System.out.println(Thread.currentThread());
}
public static void main(String[] args)
{ A a1 = new A();
Thread t1 = new Thread(a1, "First Child Thread");
A a2 = new A();
Thread t2 = new Thread(a2, "Second Child Thread");
t1.start();
t2.start(); } }
• Output:
Thread[First Child Thread,5,main]
Thread[Second Child Thread,5,main]
Thread[First Child Thread,5,main]
Thread[Second Child Thread,5,main]
Join and IsAlive Method in Java
• Sometimes one thread needs to know when other thread is
terminating. In java, isAlive() and join() are two different
methods that are used to check whether a thread has finished its
execution or not.
• The isAlive() method returns true if the thread upon which it is
called is still running otherwise it returns false.
final boolean isAlive()
• Example
public class MyThread extends Thread
{
public void run()
{
System.out.println("r1 ");
try {
Thread.sleep(500);
}
catch(InterruptedException ie)
{
// do something
}
System.out.println("r2 ");
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
t2.start();
System.out.println(t1.isAlive());
System.out.println(t2.isAlive());
}}
• Output
r1
true
true
r1
r2
r2
• The join() method in Java is used when a thread needs
to wait for another thread to finish its execution.
• In other words, this method is used to wait the current
thread until the thread that has called the join()
method completes its execution.
• The join() method is an instance method and it is
always called by an object of Thread Class.
• The general syntax to call join() method in java
program is as follows:
ThreadName.join(); // ThreadName is reference variable of Thread
class.
Calling join() method halts the execution of current thread (calling thread) until the
ThreadName thread completes its execution (normal or abnormal termination).
This means that the current thread will wait until the called thread completes its
execution.
• Thread class provides join() method in three flavors.
1.final void join() throws InterruptedException
2.public final void join(long milliseconds)
3.public final void join(long millisecond, nanoseconds)
• If we use join() method with timeout, the caller thread
will wait until the thread on which it is called, is
terminated or the time limit has elapsed.
• This method throws an exception
named InterruptedException when it is interrupted
while waiting to join. Therefore, it must be enclosed in
a Java try-catch block.
Java Synchronization
• Synchronization is a process of handling resource accessibility
by multiple thread requests.
• The main purpose of synchronization is to avoid thread
interference.
• At times when more than one thread try to access a shared
resource, we need to ensure that resource will be used by
only one thread at a time.
• The process by which this is achieved is called
synchronization.
• The synchronization keyword in java creates a block of code
referred to as critical section.
• General Syntax:
synchronized (object)
{
//statement to be synchronized
}
Every Java object with a critical section of code gets
a lock associated with the object. To enter critical
section a thread need to obtain the
corresponding object's lock.
Thread Methods in Java
Why use Synchronization in Java?
• If you start with at least two threads inside a program, there
might be a chance when multiple threads attempt to get to
the same resource. It can even create an unexpected outcome
because of concurrency issues.
• Consider an example, Suppose we have two different
threads T1 and T2, T1 starts execution and save certain values
in a file temporary.txt which will be used to calculate some
result when T1 returns. Meanwhile, T2 starts and before T1
returns, T2 change the values saved by T1 in the file
temporary.txt (temporary.txt is the shared resource). Now
obviously T1 will return wrong result.
• To prevent such problems, synchronization was introduced.
With synchronization in above case, once T1 starts
using temporary.txt file, this file will be locked(LOCK mode),
and no other thread will be able to access or modify it until T1
returns.
• To prevent such problems, synchronization
was introduced. With synchronization in
above case, once T1 starts
using temporary.txt file, this file will
be locked(LOCK mode), and no other thread
will be able to access or modify it until T1
returns.
Object Lock in Java
• The code in Java program can be synchronized with the help of a lock. A lock has
two operations: acquire and release. The process of acquiring and releasing
object lock (monitor) of an object is handled by JVM. In Java programming
language, every object has a default object lock that can be used to lock on a
thread. This object lock is also known as monitor that allows only one thread to
use the shared resources (objects) at a time.
• To acquire an object lock on a thread, we call a method or a block with the
synchronized keyword. Before entering a synchronized method or a block, a
thread acquires an object lock of the object.
• On exiting synchronized method or block, thread releases the object’ monitor
lock. A thread can again acquire the object’ monitor lock as many times as it
wants.
• Object lock is like a room with only one door. A person enters the room and locks
the door from inside. The second person who wants to enter the room will wait
until the first person come out.
• Similarly, a thread also locks the object after entering it, the next thread cannot
enter it until the first thread comes out. Since the object is locked mutually on
threads, therefore, this object is called mutex (mutually exclusive lock).
Rules for synchronizing shared
resources in Java
• In the Java program, there must mainly three rules to be
followed when synchronizing share resources. The rules are as
follows:
1. A thread must get an object lock associated with it before
using a shared resource. If a thread has an object lock of the
shared resource, Java runtime system (JVM) will not allow
another thread to access the shared resource.
If a thread is trying to access the shared resource at the same
time, it is blocked by JVM and has to wait until the resource is
available.
2. Only methods or blocks can be synchronized. Variables or
classes cannot be synchronized.
3. Only one lock is associated with each object or shared
resource.
How can we achieve Synchronization
in Java?
• There are two ways by which we can achieve or implement
synchronization in Java. That is, we can synchronize the
object. They are:
1. Synchronized Method
2. Synchronized Block
• When we declare a synchronized keyword in the header of a
method, it is called synchronized method. Once a method is
made synchronized, and thread calls the synchronized
method, it gets locked on the method.
• All other threads will have to wait for the current thread to
release the lock. Using the synchronized keyword, we can
synchronize the entire method.
• For example, if you want to synchronize the code of show()
method, add the synchronize before the method name. The
syntax to make method synchronized is as follows:
• Syntax:
synchronized void show()
{
// statements to be synchronized
}
• Since the code inside the method is synchronized, the code
will not be available to more than one thread at a time.
• Synchronizing a block of code is another way of
controlling the execution of thread. The general syntax
to make a block of code synchronized is as follows:
Syntax:
synchronized(object)
{
// statements to be synchronized
}
Here, object is a reference variable of an object that
has to be locked or synchronized.
The statements within the synchronized block are
available to only one thread at a time.
Key Points to Remember
1. There are two types of synchronization: Process synchronization and
Thread synchronization.
2. Thread synchronization in Java program is achieved through the
monitor (lock) concept.
3. A monitor is an object that can block and resume threads.
4. Every object in Java programming language has an associated
monitor.
5. Java programming language supports only two kinds of threads
synchronization: Mutual exclusion synchronization and Conditional
synchronization.
6. In mutual exclusion synchronization, only a single thread is allowed
to have access to code at a time.
7. In conditional synchronization, multiple threads are allowed to work
together to get results.
Synchronized Method in Java

• When we declare a synchronized keyword in the header of a


method, it is called synchronized method in Java.
• Using the synchronized keyword, we can synchronize all the
methods of any class.
• When a method is declared as synchronized, JVM creates a monitor
(lock). To enter the monitor, the synchronized method is called. The
thread that calls the synchronized method first, acquires object
lock.
• If the object lock is not available, calling thread is blocked and it has
to wait until the lock becomes available.
• As long as thread holds lock (monitor), no other thread can enter
the synchronized method and will have to wait for the current
thread to release the lock on the same object. Look at the below
figure to understand better.
Once a thread completes the execution of code inside the synchronized method, it
releases object lock and allows other thread waiting for this lock to proceed.
That is once a thread completes its work using synchronized method, it will hand over
to the next thread that is ready to use the same resource.
Example-15
class First
{
synchronized public void display(String msg)
{
System.out.print ("["+msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]");
}}
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{ fobj = fp;
msg = str;
start();
}
public void run()
{
fobj.display(msg);
}
}
public class MyThread
{
public static void main (String[] args)
{
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1= new Second(fnew,"new");
Second ss2 = new Second(fnew, "programmer");
}}
Output:
[welcome]
[programmer]
[new]
Using Synchronized block

• If want to synchronize access to an object of a


class or only a part of a method to be
synchronized then we can use synchronized
block for it. It is capable to make any part of
the object and method synchronized.
Example-16
class First
{
public void display(String msg)
{
System.out.print ("["+msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]"); } }
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{
fobj = fp;
msg = str;
start();
}
public void run()
{ synchronized(fobj) //Synchronized block
{ fobj.display(msg);
} } } public class MyThread { public static void main (String[] args) {
First fnew = new First(); Second ss = new Second(fnew, "welcome");
Second ss1= new Second (fnew,"new"); Second ss2 = new
Second(fnew, "programmer"); } }
public class MyThread
{
public static void main (String[] args)
{
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1= new Second (fnew,"new");
Second ss2 = new Second(fnew,
"programmer");
}}
• Output

[welcome]
[new]
[programmer]
Difference between synchronized
keyword and synchronized block
• When we use synchronized keyword with a method, it
acquires a lock in the object for the whole method. It
means that no other thread can use any synchronized
method until the current thread, which has invoked it's
synchronized method, has finished its execution.
• synchronized block acquires a lock in the object only
between parentheses after the synchronized keyword.
This means that no other thread can acquire a lock on
the locked object until the synchronized block exits.
But other threads can access the rest of the code of the
method.
1.Which is more preferred - Synchronized method or
Synchronized block?
In Java, synchronized keyword causes a performance
cost. A synchronized method in Java is very slow and
can degrade performance. So we must use
synchronization keyword in java when it is necessary
else, we should use Java synchronized block that is
used for synchronizing critical section only.
2. Can we synchronize static method in Java?
Yes, a static method can also be synchronized. In this
case, the lock is placed on the class, not on the object.
The thread will execute the method body only when
the lock is placed on the class. It will hold the lock until
it leaves the method body.
Deadlock in Java

• We know that when more than one threads are used in a


program, they share resources. At a time, a particular
resource is allotted to a thread that gains object lock for
that resource.
• Deadlock in Java is a situation that occurs when a thread is
waiting for an object lock, that is acquired by another
thread, and second thread is waiting for an object lock that
is acquired by the first thread.
• Since both threads are waiting for each other to release the
lock simultaneously, this condition is called deadlock in
Java. The object locks acquired by both threads are not
released until their execution is not completed.
• Suppose that thread1 and thread2 are two threads that
are in a deadlock. The thread thread1 holds the lock for
the resource R1 and waits for resource R2 that is
acquired by thread thread2.
• At the same time, thread thread2 holds the lock for the
resource R2 and waits for R1 resource that is acquired
by thread thread1. But thread2 cannot release the lock
for resource R2 until it gets hold of resource R1.
• Since both threads are waiting for each other to unlock
resources R1 and R2, therefore, these mutually
exclusive conditions are called deadlock in Java.
Realtime Example of Deadlock in Java

• A simple real-time example of deadlock is that suppose


there are two friends John and Jerry that are drawing a
diagram. During drawing, John needs an eraser, so he will
use (lock) the eraser.
• Meanwhile, Jerry needs ruler, so he will use (lock) the ruler.
Currently, eraser and ruler are not occupied by any of the
friends. Now John needs a ruler to continue his drawing.
But Jerry will not give it because he is using it currently.
• Later on, Jerry needs an eraser but John will not give it as
his drawing is not completed because of waiting for the
ruler. Thus, none of the friends will release stationary
objects and both will wait infinitely for each other to
release stationary. This situation is called deadlock in Java.
• Similarly, assume that there are two threads t1 and t2.
Both threads are running concurrently
(simultaneously). During execution, thread t1 is waiting
for data that is locked by thread t2 and t2 is waiting for
data that is locked by thread t1.
• In this case, none of the threads will unlock the lock
because of not completing their execution process.
This situation is called deadlock.
• When thread deadlock occurs in a program, the further
execution of program will stop. Therefore, thread
deadlock is a drawback in a program. We should take
care to avoid deadlock while coding.
How to avoid Deadlock in Java
Program?
• There is no precise solution to overcome the problem of deadlock in a
program. It depends on the logic used by the programmer. The
programmer should create his program in such a way that it does not form
the problem of deadlock.
• A deadlock in a program can be prevented if any of the four conditions are
not met. They are:
1. Mutual Exclusive Condition: If every resource is shared by multiple
threads, deadlock would never occur.
2. Hold and Wait Condition: This condition can be eliminated when a thread
is prohibited to wait for more resources while already holding a certain
resource. It can be achieved when we declare all resources at the very
beginning that are expected to use by a thread.
3. No Preemption Condition: This condition can be eliminated if a
thread holding a certain resource is denied for further request. That
thread must unlock its original resource. If necessary request them
again together with additional resource.
4. Circular Wait Condition: This is the easiest way to avoid deadlock
than the above three. There are two ways to eliminate deadlock.
First way: It can be achieved if a thread is to force to hold only one
resource at a time. If it needs another resource, it must first release
that resource that is held by it and then requests another.
Second way: It can be achieved by acquiring resources (locks) in a
specific order and releasing them in reverse order so that a thread
can only continue to acquire a resource if it held the other one.

You might also like