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

VIPS OOPS Unit 3 Multithreading

Uploaded by

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

VIPS OOPS Unit 3 Multithreading

Uploaded by

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

Multithreading

By Dr. Nishtha Kansal


Multithreaded

• Multithreading is a Process to execute multiple threads at the same time without


dependency of other thread called Multithreading .
• Java supports multithreaded programming, which allows you to write programs that
do many things simultaneously.
• A multithreaded program contains two or more parts that can run concurrently. Each
part of such a program is called a thread.
• Thread is a predefined class which is available in java.lang package. Thread is a
basic unit of CPU and is well known as for independent execution. Multithreading
enables you to write very efficient programs that make maximum use of the CPU,
because idle time can be kept to a minimum. This is especially important for the
interactive, networked environment in which Java operates, because idle time is
common.
What Kind of Applications Use
Multithreading?

• Any kind of application which has distinct tasks which


can be performed independently.

 Any application with a GUI.


 Threads dedicated to the GUI can delegate the processing of user
requests to other threads.
 The GUI remains responsive to the user even when the user's
requests are being processed.
What Kind of Applications Use
Multithreading?

Any application which requires asynchronous response


 Network based applications are ideally suited to multithreading. 
1) Data can arrive from the network at any time. 
2) In a single threaded system, data is queued until the thread can read
the data. 
3) In a multithreaded system, a thread can be dedicated to listening for
data on the network port. 
4) When data arrives, the thread reads it immediately and processes it
or delegates its processing to another thread.
Thread Support in Java

• The Java Virtual machine has its own runtime threads.


• Used for garbage collection.
• Threads are represented by a Thread class.
• A thread object maintains the state of the thread.
• It provides control methods such as interrupt, start, sleep, yield, wait.
• When an application executes, the main method is executed by a single
thread.
• If the application requires more threads, the application
must create them.
How does a Thread run?

• The thread class has a run() method.


• run() is executed when the thread's start()
method is invoked.

• The thread terminates if the run method


terminates.
• To prevent a thread from terminating, the
run method must not end.
• run methods often have an endless loop to
prevent thread termination.

• One thread starts another by calling its start


method.
• The sequence of events can be confusing to
those more familiar with a single threaded
model.
Types in Multitasking in Java
It is important to understand the difference between the two. ,It is the way of executing multiple tasks at a time
executing them concurrently over a specified period. Multitasking is done in two ways.There are two distinct
types of multitasking:
1. Process-based
2. Thread-based.
Process-based multitasking :It is also called multiprocessing where each process has its address in memory, i.e.,
each process allocates separate memory area.A process is, a program that is executing. Thus, process-based
multitasking is the feature that allows your computer to run two or more programs concurrently. For example,
process-based multitasking enables you to run the Java compiler at the same time that you are using a text editor.
In process_x0002_based multitasking, a program is the smallest unit of code that can be dispatched by the
scheduler.process-based multitasking deals with the “big picture”.
Thread-based multitasking:This thread-based multitasking is also termed as multithreading where threads share
the same address space.The thread is the smallest unit of dispatchable code. This means that a single program can
perform two or more tasks simultaneously. For instance, a text editor can format text at the same time that it is
printing, as long as these two actions are being performed by two separate threads. Thus, thread-based
multitasking handles the details.
Life Cycle of a Thread in Java

• A thread goes through various stages of its life cycle. Example, first of all, a
thread is born, started its tasks, run a sequence of tasks concurrently, and then
dies. Here is the diagram of the various stages of a life cycle.
• New Thread: A new thread begins its life cycle in the new state. The process
remains in this condition until the program starts the thread.
• Runnable: As soon as the new thread starts, the thread status becomes Runnable.
At this stage, a thread is considered to execute its function or working.
• Not Runnable: A Runnable thread when entered the time of waiting for the state
for a specific interval of time. That time, the thread is not in Runnable condition.
• Dead / Terminated: The Runnable thread enters the end stage when it completes
its tasks.
Life Cycle of a Thread in Java
Life Cycle of a Thread in Java
Life Cycle of a Thread in Java

 New: When instance of thread is created using new operator it is in new state,
but the start() method has not been invoked on the thread yet, thread is not
eligible to run yet.

 Runnable: When start() method is called on thread it enters runnable state.


As soon as Thread enters runnable state it is eligible to run, but not running.
(Thread scheduler has not scheduled the Thread execution yet.)

 Running: Thread scheduler selects thread to go from runnable to running


state. In running state Thread starts executing by entering run() method.
Life Cycle of a Thread in Java

 Waiting/Blocked/sleeping: In this state a thread is not eligible to run.


• By calling wait() method thread go from running to waiting state. In waiting state it will
wait for other threads to release object monitor/lock. Once notify() or notifyAll() method is
called object monitor/lock becomes available and thread can again return to runnable state.
• By calling sleep() method thread go from running to sleeping state. In sleeping state it will
wait for sleep time to get over. Once specified sleep time is up thread can again return to
runnable state.
• Suspend() method can be used to put thread in waiting state and resume() method is the only
way which could put thread in runnable state.
Terminated (Dead): A thread is considered dead when its run() method completes. Once
thread is dead it cannot be started again doing so will throw runtimeException i.e.
IllegalThreadStateException. destroy() method puts thread directly into dead state.
Life Cycle of a Thread in Java
The Thread Class
• The Thread class defines several methods that help manage threads. The ones that will be used in
this chapter are shown here:
Method Meaning
getName () Obtain a thread’s name.

getPriority () Obtain a thread’s priority


isAlive() Determine if a thread is still running.
join() Wait for a thread to terminate.
run() Entry point for the thread.
sleep() Suspend a thread for a period of time.
start() Start a thread by calling its run method.

setPriority(int It changes the priority of the thread.


newpriority)
yield () It causes current thread on halt and other threads to execute.
The Main Thread

• When a Java program starts up, one thread begins running immediately.
This is usually called the main thread of your program, because it is
the one that is executed when your program begins. The main thread is
important for two reasons:
• It is the thread from which other “child” threads will be born.
• Often, it must be the last thread to finish execution because it performs
various shutdown actions.
Although the main thread is created automatically when your program is
started, it can be controlled through a Thread object.
The Main Thread Example

//Controlling the main Thread.


class CurrentThreadDemo { Output:
public static void main(String args[]) { Current thread: Thread[main,5,main]
Thread t = Thread.currentThread(); After name change: Thread[My Thread,5,main]
System.out.println("Current thread: " + t); 5
// change the name of the thread 4
t.setName("My Thread"); 3
System.out.println("After name change: " + 2t);
try { 1
for(int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}}}
The Main Thread Example

• Output :This displays, inorder: Current thread(Thread name,Thread


Prority,Thread Group) display three values
• the name of the thread, its priority, and the name of its group. By
default, the name of the main thread is main. Its priority is by default
is 5, which is the default value, and main is also the name of the group
of threads to which this thread belongs.
• A thread group is a data structure that controls the state of a collection
of threads as a whole. After the name of the thread is changed, t is
again output. This time, the new name of the thread is displayed.
Create a Thread by Two ways

Java defines two ways in which this can be accomplished:


• By implement the Runnable interface.
• By extend the Thread class, itself.
The following two sections look at each method, in turn.
The easiest way to create a thread is to create a class that implements the
Runnable interface. To implement Runnable, a class need only
implement a single method called run( ), which is declared like this:
• public void run( )
Running Threads
Example
Calling t.run() does not
class Mythread implements Runnable{
public void run(){
start a thread, it is just a
System.out.println(“Thread Started”);} simple method call.
} Creating an object does not
class mainclass { create a thread, calling
public static void main(String args[]){
start() method creates the
Thread t = new Thread(new mythread( ));
// This is the way to instantiate a
thread
thread implementing runnable interface
t.start(); // starts the thread by running
the run method
}}
Creating a Thread using Runnable
Interface

Create a Thread by Implementing a Runnable Interface


If your class is intended to be executed as a thread then you can achieve this by implementing a Runnable interface. You will need to follow
three basic steps −
Step 1
As a first step, you need to implement a run() method provided by a Runnable interface. This method provides an entry point for the thread and
you will put your complete business logic inside this method. Following is a simple syntax of the run() method −
public void run( )
Step 2
As a second step, you will instantiate a Thread object using the following constructor −
Thread(Runnable threadObj, String threadName);
Where, threadObj is an instance of a class that implements the Runnable interface and threadName is the name given to the new thread.
Step 3
Once a Thread object is created, you can start it by calling start() method, which executes a call to run( ) method. Following is a simple syntax
of start() method −
void start();
• This will produce the following result −
Creating a Thread using Runnable
Interface

Inside NewThread’s constructor, a new Thread object is created by the


following
statement:
t = new Thread(this, "Demo Thread");
Passing this as the first argument indicates that you want the new thread
to call the run( ) method on this object.Next, start( ) is called, which
starts the thread of execution beginning at the run( ) method. This
causes the child thread’s for loop to begin. After calling start( ),
NewThread’s constructor returns to main( ).
Creating a Thread using Runnable
Interface
• Create a second thread. System.out.println("Exiting child thread.");
class NewThread implements Runnable { } } Output:
Thread t; class ThreadDemo { Child thread:
NewThread() { public static void main(String args[]) { Thread[Demo
// Create a new, second thread new NewThread(); // create a new thread Thread,5,main]
t = new Thread(this, "Demo Thread"); Main Thread: 5
try { Child Thread: 5
System.out.println("Child thread: " + t); for(int i = 5; i > 0; i--) { Child Thread: 4
t.start(); // Start the thread System.out.println("Main Thread: " + i); Main Thread: 4
} Child Thread: 3
Thread.sleep(1000);
// This is the entry point for the second thread. Child Thread: 2
public void run() { }
Main Thread: 3
try {for(int i = 5; i > 0; i--) { } catch (InterruptedException e) { Child Thread: 1
System.out.println("Child Thread: " + i); System.out.println("Main thread interrupted.");
Exiting child thread.
Thread.sleep(500); } Main Thread: 2
Main Thread: 1
}} catch (InterruptedException e) { System.out.println("Main thread exiting.");
Main thread exiting.
System.out.println("Child interrupted.");} } }
Create a Thread by Extending a Thread
Class
The second way to create a thread is to create a new class that extends Thread class using the following
two simple steps. This approach provides more flexibility in handling multiple threads created using available
methods in Thread class.
Step 1
You will need to override run( ) method available in Thread class. This method provides an entry point for the
thread and . Following is a simple syntax of run() method −

public void run( )


Step 2
Once Thread object is created, you can start it by calling start() method, which executes a call to run( ) method.
Following is a simple syntax of start() method −

void start( );
Create a Thread by Extending a Thread
Class // Create a second thread by extending Thread
System.out.println("Child interrupted.");
class NewThread extends Thread { } OUTPUT:
System.out.println("Exiting child thread."); Child thread:
NewThread() {
}}
// Create a new, second thread Thread[DemoThread,5,main]
class ExtendThread {
public static void main(String args[]) {
Main Thread: 5
super("Demo Thread");
new NewThread(); // create a new thread Child Thread: 5
System.out.println("Child thread: " + this);
try { Child Thread: 4
start(); // Start the thread Child Thread: 3
for(int i = 5; i > 0; i--) {
} System.out.println("Main Thread: " + i); Main Thread: 4
// This is the entry point for the second thread. Thread.sleep(1000); Child Thread: 2
} Main Thread: 3
public void run() {
} catch (InterruptedException e) { Child Thread: 1
try { System.out.println("Main thread interrupted.");
Exiting child thread.
for(int i = 5; i > 0; i--) { }
System.out.println("Main thread exiting.");
Main Thread: 2
System.out.println("Child Thread: " + i); Main Thread: 1
}}
Thread.sleep(500); Main thread exiting.
} BUILD SUCCESSFUL (total time: 5
} catch (InterruptedException e) { seconds)
Create a Thread by Extending a Thread
Class
The child Thread is created by instantiating an object of
NewThread, which is derived from Thread.
Notice the call to super( ) inside NewThread. This invokes the
following form of the
Thread constructor:
public Thread(String threadName)
Here, threadName specifies the name of the thread.
Multithreading catch (InterruptedException e) {
/ Create multiple threads. System.out.println(name + "Interrupted"); OUTPUT:
class NewThread implements Runnable { The output from this program is shown here:
}
New thread: Thread[One,5,main]
String name; // name of thread System.out.println(name + " exiting."); New thread: Thread[Two,5,main]
Thread t; New thread: Thread[Three,5,main]
}}
NewThread(String threadname) { One: 5
System.out.println(name + " exiting.");} } Two: 5
name = threadname;
class MultiThreadDemo { Three: 5
t = new Thread(this, name); One: 4
public static void main(String args[]) {
System.out.println("New thread: " + t); Two: 4
new NewThread("One"); // start threads Three: 4
t.start(); // Start the thread
new NewThread("Two"); One: 3
}
Three: 3
// This is the entry point for thread. new NewThread("Three");
Two: 3
public void run() { try { One: 2
try { // wait for other threads to end Three: 2
Two: 2
for(int i = 5; i > 0; i--) { Thread.sleep(10000); One: 1
System.out.println(name + ": " + i); } catch (InterruptedException e) { Three: 1
Thread.sleep(1000); System.out.println("Main thread Interrupted");
Two: 1
} One exiting.
} Two exiting.
} System.out.println("Main thread exiting."); Three exiting.
Main thread exiting.
}}
Thread Priorities
Java assigns each thread a priority that concludes that how a thread will
be treated concerning others. Thread priorities are integers that specify
the relative priority of one thread with another. Thread priorities are
used for deciding when to switch from one running thread to another. It
is called a context switch.
Thread Priorities

• Every thread is assigned a priority (between 1 and 10).


• The default is 5.
• The higher the number, the higher the priority.
• Can be set with setPriority(int aPriority).

• The standard mode of operation is that the scheduler executes threads


with higher priorities first.
• This simple scheduling algorithm can cause problems. Specifically,
one high priority thread can become a "CPU hog".
• A thread using vast amounts of CPU can share CPU time with other
threads by invoking the yield() method on itself.
Types of Priority

In Java, a thread's priority is an integer in the range


1 to 10. The larger the integer, the higher the
Changing a Thread’s Priority
priority. The thread scheduler uses this integer from
each thread to determine which one should be
The getPriority() instance method
allowed to execute. The Thread class defines three returns the integer that represents
types of priorities: its priority. The setPriority()
• Minimum priority instance method takes an integer
• Normal priority between 1 and 10 for changing the
• Maximum priority thread's priority. If we pass a value
outside the 1-10 range, the method
The Thread class defines these priority types as
constants MIN_PRIORITY, NORM_PRIORITY, will throw an error.
and MAX_PRIORITY, with values 1, 5, and 10,
respectively. NORM_PRIORITY is the default
priority for a new Thread.
THREAD PRIORITY Example
• class MultithreadDemo extends Thread{
public void run(){
System.out.println("Thread ID: " + Thread.currentThread().getId());
Output:
System.out.println("Thread Priority: " + Thread.currentThread().getPriority());
}} Thread ID: 12
Thread ID: 11
public class ThreadPriority { Thread Priority: 10
public static void main(String[] args){ Thread Priority: 1
MultithreadDemo t1=new MultithreadDemo();
MultithreadDemo t2= new MultithreadDemo();
t1.setPriority(1);//minimum Priority
t2.setPriority(Thread.MAX_PRIORITY);//Maximum priority by default 10
t1.start();
t2.start(); }}
Using isAlive( ) and join( )
How can one thread know when another thread has ended?
Thread provides a means by which you can answer this question.
Two ways exist to determine whether a thread has finished. First, you can call isAlive( ) on
the thread. This method is defined by Thread, and its general form is shown here:
final boolean isAlive( )
The isAlive( ) method returns true if the thread upon which it is called is still running. It
returns false otherwise.
While isAlive( ) is occasionally useful, the method that you will more commonly use to wait
for a thread to finish is called join( ), shown here:
final void join( ) throws InterruptedException
This method waits until the thread on which it is called terminates. Its name comes from the
concept of the calling thread waiting until the specified thread joins it. Additional forms of
join( ) allow you to specify a maximum amount of time that you want to wait for the
specified thread to terminate.
Example Using isAlive() and join() to
wait for threads to finish.
// Using join() to wait for threads to finish. class DemoJoin {
class NewThread implements Runnable { public static void main(String args[]) {
String name; // name of thread NewThread ob1 = new NewThread("One");
Thread t; NewThread ob2 = new NewThread("Two");
NewThread(String threadname) { NewThread ob3 = new NewThread("Three");
name = threadname; System.out.println("Thread One is alive: "+ ob1.t.isAlive());
t = new Thread(this, name); System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("New thread: " + t); System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
t.start(); // Start the thread // wait for threads to finish
} try {
// This is the entry point for thread. System.out.println("Waiting for threads to finish.");
public void run() { ob1.t.join();
try { ob2.t.join();
for(int i = 5; i > 0; i--) { ob3.t.join();
System.out.println(name + ": " + i); } catch (InterruptedException e) {
Thread.sleep(1000); System.out.println("Main thread Interrupted");
} }
} catch (InterruptedException e) { System.out.println("Thread One is alive: "+ ob1.t.isAlive());
System.out.println(name + " interrupted."); System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
} System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
System.out.println(name + " exiting."); System.out.println("Main thread exiting.");
}} }}
Output of Alive() and join() method
Output from above program is shown here. (Your output may vary One: 3
based on processor speed and task load.) Two: 3
New thread: Thread[One,5,main] Three: 3
New thread: Thread[Two,5,main] One: 2
New thread: Thread[Three,5,main] Two: 2
Thread One is alive: true Three: 2
Thread Two is alive: true One: 1
Thread Three is alive: true Two: 1
Waiting for threads to finish. Three: 1
One: 5 Two exiting.
Two: 5 Three exiting.
Three: 5 One exiting.
One: 4 Thread One is alive: false
Two: 4 Thread Two is alive: false
Three: 4 Thread Three is alive: false
Main thread exiting.
Concurrent Access to Data

 Those familiar with databases will understand that concurrent


access to data can lead to data integrity problems.
 Specifically, if two sources attempt to update the same data at

the same time, the result of the data can be undefined.


 The outcome is determined by how the scheduler
schedules the two sources.
 Since the schedulers activities cannot be predicted, the outcome
cannot be predicted
Concurrent Access to Data

• Databases deal with this mechanism through "locking“.


• If a source is going to update a table or record, it can lock the
table or record until such time that the data has been successfully
updated.
• While locked, all access is blocked except to the source
which holds the lock.
• Java has the equivalent mechanism. It is called synchronization.
• Java has a keyword called synchronized.
Synchronization
What happen if, the threads wants to access the shared resources ?
There must be an option so that not more one thread will be able to use a
shared resource . This is achieved by a process known as synchronisation.
• Key to synchronization is the concept of the monitor (also called a
semaphore). A monitor is an object that is used as a mutually exclusive
lock or mutex.
• Only one thread can own a monitor at a given time. When one
thread owns a monitor, others have to wait for that resource.
• The simplest way to use synchronization is by declaring one or more
methods to be synchronized.
Synchronization

• Synchronization prevent data corruption.


• Synchronization allows only one thread to perform an operation on a
object at a time.
• If multiple threads require an access to an object, synchronization
helps in maintaining consistency.
Example
public class Counter{ private int count = 0; In this example, the counter tells
how many access has been made.
public int getCount()
{ return count;  If a thread is accessing
setCount and updating count
} and another thread is
accessing getCount at the
public setCount( ) same time, there will be
inconsistency in the
{
value of count.
count++;
}
}
Fixing the example
public class Counter{ private static
int count = 0;
• By adding the synchronized keyword
we make sure that when one thread is
public synchronized int in the setCount method the other
getCount()
threads are all in waiting state.
{
return count; • The synchronized keyword places a
} lock on the object, and hence locks
all the other methods which have the
public synchoronized
keyword synchronized. The lock
setCount(int count)
does not lock the methods without
{ this.count = count; the keyword synchronized and hence
} they are open to access by other
threads.
Synchronization

• Only one thread can own a monitor at a This is the general form of the
given time. When a thread acquires a synchronized statement:
lock, it is said to have entered the
monitor. synchronized(object) {
• All other threads attempting to enter the // statements to be synchronized
locked monitor will be suspended until
the first thread exits the monitor. }
• These other threads are said to be
waiting for the monitor.
• While a thread is inside a synchronized
method, all other threads that try to call
it (or any other synchronized method)
on the same instance have to wait.
Synchronization
This example is not synchronized.

class Callme { public void run() {


void call(String msg) { target.call(msg);
System.out.print("[" + msg); OUTPUT:
}}
try {Thread.sleep(1000);} catch(InterruptedException e) {
System.out.println("Interrupted");} class Synch {
[Hello[Sync[World]
System.out.println("]");} } public static void main(String args[])
] {
class Caller implements Runnable {
Callme target = new Callme(); ]
String msg;
Callme target; Caller ob1 = new Caller(target, "Hello");
Thread t; Caller ob2 = new Caller(target, "Synchronized");
public Caller(Callme targ, String s) { Caller ob3 = new Caller(target, "World");// wait for threads
target = targ; to end
msg = s; try {ob1.t.join();ob2.t.join();ob3.t.join();
t = new Thread(this);
t.start(); } catch(InterruptedException e) {
} System.out.println("Interrupted");
}}}
Example uses a synchronized block.
// This program uses a synchronized block. // synchronize calls to call()
class Callme { public void run() {
void call(String msg) { synchronized(target) { // synchronized block
System.out.print("[" + msg); Output :
target.call(msg);
try { [Hello]
}}} [Synchronized]
Thread.sleep(1000);
class Synch1 { [World]
} catch (InterruptedException e) {
System.out.println("Interrupted");
public static void main(String args[]) {
} Callme target = new Callme();
System.out.println("]");} } Caller ob1 = new Caller(target, "Hello");
class Caller implements Runnable { Caller ob2 = new Caller(target,
String msg; "Synchronized");
Callme target; Caller ob3 = new Caller(target, "World");
Thread t; // wait for threads to end
public Caller(Callme targ, String s) { try {ob1.t.join(); ob2.t.join(); ob3.t.join();}
target = targ; catch(InterruptedException e) {
msg = s; t = new Thread(this);t.start();} System.out.println("Interrupted");} } }
Interthread Communication

• The wait(), notify(), notifyAll()methods are used for interthread communication.


These are functions of Object class.

• These method are implemented as final in Object. All three method can be called
only from within a synchronized context.
• wait() tells calling thread to give up monitor and go to sleep until some other
thread enters the same monitor and call notify.

• notify() wakes up a thread that called wait() on same object.

• notifyAll() wakes up all the thread that called wait() on same object.
Interthread Communication

wait() sleep()
called from synchronised no such requirement
block
monitor is released monitor is not released
awake when notify() or not awake when notify() or
notifyAll() method is called. notifyAll() method is called
not a static method static method
wait() is generaly used on sleep() method is simply used to
condition put your thread on sleep.

You might also like