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

SD Multithreading

Uploaded by

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

SD Multithreading

Uploaded by

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

Multithreading

Dr Sujit Das
NIT Warangal
Introduction
• Multithreading in Java is a process of executing multiple
threads simultaneously.
• A thread is a lightweight sub-process, the smallest unit of
processing. Multiprocessing and multithreading, both are used
to achieve multitasking.
• However, we use multithreading than multiprocessing because
threads use a shared memory area.
• They don't allocate separate memory area so saves memory,
and context-switching between the threads takes less time than
process.
• Java Multithreading is mostly used in games, animation, etc.
Advantages of Java Multithreading
• It doesn't block the user because threads are independent
and you can perform multiple operations at the same time.
• You can perform many operations together, so it saves
time.
• Threads are independent, so it doesn't affect other threads if
an exception occurs in a single thread.
Multitasking
• Multitasking is a process of executing multiple tasks simultaneously. We
use multitasking to utilize the CPU. Multitasking can be achieved in two
ways:
• Process-based Multitasking (Multiprocessing)
• Thread-based Multitasking (Multithreading)
1) Process-based Multitasking (Multiprocessing)
• Each process has an address in memory. In other words, each process
allocates a separate memory area.
• A process is heavyweight.
• Cost of communication between the process is high.
• Switching from one process to another requires some time for saving and
loading registers, memory maps, updating lists, etc.
2) Thread-based Multitasking (Multithreading)
• Threads share the same address space.
• A thread is lightweight.
• Cost of communication between the thread is low.
What is Thread in java
• A thread is a lightweight subprocess,
the smallest unit of processing.
• It is a separate path of execution.
• Threads are independent.
• If there occurs exception in one
thread, it doesn't affect other
threads.
• It uses a shared memory area.
Java Thread Methods
S.N. Modifier and Method Description
Type
1) void start() It is used to start the execution of the thread.

2) void run() It is used to do an action for a thread.


3) static void sleep() It sleeps a thread for the specified amount of time.

4) static Thread currentThread() It returns a reference to the currently executing thread object.

5) void join() It waits for a thread to die.


6) int getPriority() It returns the priority of the thread.
7) void setPriority() It changes the priority of the thread.
8) String getName() It returns the name of the thread.
9) void setName() It changes the name of the thread.
10) long getId() It returns the id of the thread.
Java Thread Methods
11) boolean isAlive() It tests if the thread is alive.
12) static void yield() It causes the currently executing thread object to pause and
allow other threads to execute temporarily.

13) void suspend() It is used to suspend the thread.


14) void resume() It is used to resume the suspended thread.
15) void stop() It is used to stop the thread.
16) void destroy() It is used to destroy the thread group and all of its
subgroups.
17) boolean isDaemon() It tests if the thread is a daemon thread.
18) void setDaemon() It marks the thread as daemon or user thread.
19) void interrupt() It interrupts the thread.
20) boolean isinterrupted() It tests whether the thread has been interrupted.
Java Thread Methods

22) static int activeCount() It returns the number of active threads in the current
thread's thread group.
23) void checkAccess() It determines if the currently running thread has
permission to modify the thread.
24) static boolean holdLock() It returns true if and only if the current thread holds the
monitor lock on the specified object.
25) static void dumpStack() It is used to print a stack trace of the current thread to
the standard error stream.
26) StackTraceEle getStackTrace() It returns an array of stack trace elements representing
ment[] the stack dump of the thread.
27) static int enumerate() It is used to copy every active thread's thread group and
its subgroup into the specified array.
28) Thread.State getState() It is used to return the state of the thread.
29) ThreadGroup getThreadGroup() It is used to return the thread group to which this thread
belongs
30) String toString() It is used to return a string representation of this thread,
Java Thread Methods
31) void notify() It is used to give the notification for only one
thread which is waiting for a particular object.

32) void notifyAll() It is used to give the notification to all waiting


threads of a particular object.

33) void setContextClassLoader() It sets the context ClassLoader for the Thread.

34) ClassLoader getContextClassLoader() It returns the context ClassLoader for the thread.

35) static getDefaultUncaughtExceptionHa It returns the default handler invoked when a thread
Thread.UncaughtEx ndler() abruptly terminates due to an uncaught exception.
ceptionHandler
36) static void setDefaultUncaughtExceptionHa It sets the default handler invoked when a thread
ndler() abruptly terminates due to an uncaught exception.
Life cycle of a Thread (Thread States)
Life cycle of a Thread (Thread States)
• In Java, a thread always exists in any one of the following
states. These states are:
1.New
2.Active
3.Blocked / Waiting
4.Timed Waiting
5.Terminated
Explanation of Different Thread States
• New: Whenever a new thread is created, it is always in the new
state. For a thread in the new state, the code has not been run yet
and thus has not begun its execution.
• Active: When a thread invokes the start() method, it moves from the
new state to the active state. The active state contains two states
within it: one is runnable, and the other is running.
• Runnable:
• A thread, that is ready to run is then moved to the runnable state. In the runnable
state, the thread may be running or may be ready to run at any given instant of time.
• It is the duty of the thread scheduler to provide the thread time to run, i.e., moving the
thread the running state. A program implementing multithreading acquires a fixed
slice of time to each individual thread.
• Running: When the thread gets the CPU, it moves from the runnable to the
running state. Generally, the most common change in the state of a thread is
from runnable to running and again back to runnable.
Explanation of Different Thread States
• Blocked or Waiting:
• Whenever a thread is inactive for a span of time (not permanently)
then, either the thread is in the blocked state or is in the waiting state.
• If there are a lot of threads in the waiting or blocked state, then it is the duty
of the thread scheduler to determine which thread to choose and which one
to reject, and the chosen thread is then given the opportunity to run.
Explanation of Different Thread States
• Timed Waiting:
• Sometimes, waiting for leads to starvation.
• For example, a thread (its name is A) has entered the critical section of
a code and is not willing to leave that critical section. In such a
scenario, another thread (its name is B) has to wait forever, which
leads to starvation.
• To avoid such scenario, a timed waiting state is given to thread B.
Thus, thread lies in the waiting state for a specific span of time, and not
forever
• A real example of timed waiting is when we invoke the sleep() method
on a specific thread.
• The sleep() method puts the thread in the timed wait state.
Life cycle of a Thread (Thread States)
• Terminated: A thread reaches the termination state because of
the following reasons:
• When a thread has finished its job, then it exists or terminates normally.
• Abnormal termination: It occurs when some unusual events
such as an unhandled exception or segmentation fault.
• A terminated thread means the thread is no more in the system.
• In other words, the thread is dead, and there is no way one can
respawn (active after kill) the dead thread.
How to create a thread in Java
• There are two ways to create a thread:
1.By extending Thread class
2.By implementing Runnable interface.
• Thread class:
• Thread class provide constructors and methods to create and perform
operations on a thread.
• Commonly used Constructors of Thread class:
• Thread()
• Thread(String name)
• Thread(Runnable r)
• Thread(Runnable r, String name)
Commonly used methods of Thread class
public void run(): is used to perform action for a thread.
public void start(): starts the execution of the thread. JVM calls
the run() method on the thread.
public void sleep(long miliseconds): Causes the currently
executing thread to sleep (temporarily cease execution) for the
specified number of milliseconds.
public void join(): waits for a thread to die.
public void join(long miliseconds): waits for a thread to die
for the specified miliseconds.
public int getPriority(): returns the priority of the thread.
public int setPriority(int priority): changes the priority of the
thread.
Commonly used methods of Thread class
public String getName(): returns the name of the thread.
public void setName(String name): changes the name of the
thread.
public Thread currentThread(): returns the reference of
currently executing thread.
public int getId(): returns the id of the thread.
public Thread.State getState(): returns the state of the thread.
public boolean isAlive(): tests if the thread is alive.
public void yield(): causes the currently executing thread
object to temporarily pause and allow other threads to execute.
public void suspend(): is used to suspend the
Commonly used methods of Thread class
public void resume(): is used to resume the suspended
thread(depricated).
public void stop(): is used to stop the thread(depricated).
public boolean isDaemon(): tests if the thread is a daemon
thread.
public void setDaemon(boolean b): marks the thread as
daemon or user thread.
public void interrupt(): interrupts the thread.
public boolean isInterrupted(): tests if the thread has been
interrupted.
public static boolean interrupted(): tests if the current thread
has been interrupted.
Implementing Runnable interface
• Runnable interface:
• The Runnable interface should be implemented by any class whose
instances are intended to be executed by a thread.
• Runnable interface have only one method named run().
public void run(): is used to perform action for a thread.
• Starting a thread:
• The start() method of Thread class is used to start a newly created
thread.
• It performs the following tasks:
• A new thread starts(with new callstack).
• The thread moves from New state to the Runnable state.
• When the thread gets a chance to execute, its target run() method will run.
Java Thread Example by extending Thread
class
FileName: Multi.java
class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
Output: thread is running...
thread is running...
Java Thread Example by implementing Runnable
interface
• FileName: Multi3.java
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1); // Using the constructor Thread(Runnabl
e r)
t1.start();
}
If you are not extending the Thread class, your class object
} would not be treated as a thread object. So you need to
Output: thread is running... explicitly create the Thread class object.
Using the Thread Class: Thread(String
FileName: MyThread1.java
Name)
public class MyThread1
{
// Main method
public static void main(String argvs[])
{
// creating an object of the Thread class using the constructor Thread(String name)
Thread t= new Thread("My first thread");
// the start() method moves the thread to the active state
t.start();
// getting the thread name by invoking the getName() method
String str = t.getName();
System.out.println(str);
}
}
Output: My first thread
Using the Thread Class: Thread(Runnable r, String
name)
public class MyThread2 implements Runnable
{
public void run() {
System.out.println("Now the thread is running ...");
}
// main method
public static void main(String argvs[]) {
// creating an object of the class MyThread2
Runnable r1 = new MyThread2();
// creating an object of the class Thread using Thread(Runnable r, String na
me)
Thread th1 = new Thread(r1, "My new thread");
// the start() method moves the thread to the active state
th1.start(); Output:
// getting the thread name by invoking the getName() method
My new thread
String str = th1.getName();
System.out.println(str);
Now the thread is running ...
} }
Thread Scheduler in Java
• A component of Java that decides which thread to run or execute and
which thread to wait is called a thread scheduler in Java.
• In Java, a thread is only chosen by a thread scheduler if it is in the
runnable state. However, if there is more than one thread in the runnable
state, it is up to the thread scheduler to pick one of the threads and ignore
the other ones.
• There are two factors for scheduling a thread i.e. Priority and Time of
arrival.
• Priority: Priority of each thread lies between 1 to 10. If a thread has a
higher priority, it means that thread has got a better chance of getting
picked up by the thread scheduler.
• Time of Arrival: Suppose two threads of the same priority enter the
runnable state, then priority cannot be the factor to pick a thread from
these two threads. In such a case, arrival time of thread is considered by
the thread scheduler. A thread that arrived first gets the preference over
the other threads.
Thread Scheduler Algorithms:
• FSFS: In this scheduling algorithm, the scheduler picks the threads
thar arrive first in the runnable queue.
• Time-slicing scheduling:
• Usually, the First Come First Serve algorithm is non-preemptive,
which is bad as it may lead to infinite blocking (also known as
starvation).
• To avoid that, some time-slices are provided to the threads so
that after some time, the running thread has to give up the CPU.
Thus, the other waiting threads also get time to run their job.
Preemptive-Priority Scheduling
• Suppose there are multiple threads available in the runnable
state. The thread scheduler picks that thread that has the
highest priority.
• Since the algorithm is also preemptive, therefore, time slices
are also provided to the threads to avoid starvation.
• Thus, after some time, even if the highest priority thread has not
completed its job, it has to release the CPU because of
preemption.
Thread.sleep() in Java with Examples
• The Java Thread class provides the two variant of the sleep()
method.
• First one accepts only an arguments, whereas the other variant
accepts two arguments.
• The method sleep() is being used to halt the working of a thread
for a given amount of time.
• The time up to which the thread remains in the sleeping state is
known as the sleeping time of the thread.
• After the sleeping time is over, the thread starts its execution
from where it has left.
The sleep() Method Syntax
1.public static void sleep(long mls) throws InterruptedExceptio
n
2.public static void sleep(long mls, int n) throws InterruptedEx
ception
• mls: The time in milliseconds is represented by the parameter
mls. The duration for which the thread will sleep is given by the
method sleep().
• n: It shows the additional time up to which the programmer or
developer wants the thread to be in the sleeping state. The
range of n is from 0 to 999999.
Important Points to Remember About the
Sleep() Method
• Whenever the Thread.sleep() methods execute, it always halts
the execution of the current thread.
• Whenever another thread does interruption while the current
thread is already in the sleep mode, then the
InterruptedException is thrown.
• If the system that is executing the threads is busy, then the
actual sleeping time of the thread is generally more as
compared to the time passed in arguments.
• However, if the system executing the sleep() method has less
load, then the actual sleeping time of the thread is almost equal
to the time passed in the argument.
Example of the sleep() method in Java : on
the custom thread
class TestSleepMethod1 extends Thread{
public void run(){
for(int i=1;i<5;i++){
// the thread will sleep for the 500 milli seconds
try{Thread.sleep(500);}
catch(InterruptedException e){System.out.println(e);} Output:
System.out.println(i);
} 1
} 1
2
public static void main(String args[]){
2
TestSleepMethod1 t1=new TestSleepMethod1(); 3
TestSleepMethod1 t2=new TestSleepMethod1(); 3
t1.start(); 4
t2.start(); 4
}
}
Example of the sleep() Method in Java : on
the main thread
import java.lang.Thread;
import java.io.*;
public class TestSleepMethod2
{ // main method
public static void main(String argvs[])
{ try {
for (int j = 0; j < 5; j++)
{ // The main thread sleeps for the 1000 milliseconds, which is
1 sec
// whenever the loop runs
Thread.sleep(1000); 0
// displaying the value of the variable 1
System.out.println(j); } } 2
catch (Exception expn) 3
{ 4
// catching the exception
System.out.println(expn);
} } }
Can we start a thread twice
• No. After starting a thread, it can never be started again. If you does so,
an IllegalThreadStateException is thrown. In such case, thread will run once but for
second time, it will throw exception.
• Let's understand it by the example given below:
public class TestThreadTwice1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestThreadTwice1 t1=new TestThreadTwice1();
t1.start();
t1.start();
}
}
What if we call Java run() method directly
instead start() method?
class TestCallRun1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestCallRun1 t1=new TestCallRun1();
t1.run();//fine, but does not start a separate call st
ack
}
}

running...
What if we call Java run() method directly
instead start() method?
class TestCallRun2 extends Thread{
public void run(){
for(int i=1;i<5;i++){
try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}
Output:
System.out.println(i);
} 1
} 2
3
public static void main(String args[]){
4
TestCallRun2 t1=new TestCallRun2(); 1
TestCallRun2 t2=new TestCallRun2(); 2
t1.run(); 3
t2.run(); 4
}
}
Java join() method
• The join() method in Java is provided by the java.lang.Thread class that
permits one thread to wait until the other thread to finish its execution.
• Suppose th be the object the class Thread whose thread is doing its
execution currently, then the th.join(); statement ensures that th is finished
before the program does the execution of the next statement.
• When there are more than one thread invoking the join() method, then it
leads to overloading on the join() method that permits the developer or
programmer to mention the waiting period.
• However, similar to the sleep() method in Java, the join() method is also
dependent on the operating system for the timing, so we should not
assume that the join() method waits equal to the time we mention in the
parameters.
Example of join() Method in Java
• ThreadJoinExample.java
• TestJoinMethod1.java
Synchronization in Java
Synchronization in Java
• Synchronization in Java is the capability to control the access of
multiple threads to any shared resource.
• Java Synchronization is better option where we want to allow only
one thread to access the shared resource.
• Why use Synchronization?
• The synchronization is mainly used to
1. To prevent thread interference.
2. To prevent consistency problem.
• Types of Synchronization
• There are two types of synchronization
• Process Synchronization
• Thread Synchronization
Thread Synchronization
• There are two types of thread synchronization mutual exclusive
and inter-thread communication.
1.Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. Static synchronization.
2.Cooperation (Inter-thread communication in java)
Concept of Lock in Java
• Synchronization is built around an internal entity known as the
lock or monitor.
• Every object has a lock associated with it. By convention, a
thread that needs consistent access to an object's fields has to
acquire the object's lock before accessing them, and then
release the lock when it's done with them.
• From Java 5 the package java.util.concurrent.locks contains
several lock implementations.
Understanding the problem without
Synchronization
• TestSynchronization1.java
Java Synchronized Method
• If you declare any method as synchronized, it is known as
synchronized method.
• Synchronized method is used to lock an object for any shared
resource.
• When a thread invokes a synchronized method, it automatically
acquires the lock for that object and releases it when the thread
completes its task.
• TestSynchronization2.java
Synchronized Block in Java
• Synchronized block can be used to perform synchronization on any
specific resource of the method.
• Suppose we have 50 lines of code in our method, but we want to
synchronize only 5 lines, in such cases, we can use synchronized block.
• If we put all the codes of the method in the synchronized block, it will work
same as the synchronized method.
• Points to Remember
• Synchronized block is used to lock an object for any shared resource.
• Scope of synchronized block is smaller than the method.
• The system performance may degrade because of the slower working of
synchronized keyword.
• Java synchronized block is more efficient than Java synchronized method.
Example of Synchronized Block
• TestSynchronizedBlock1.java
Static Synchronization
• If you make any static method as synchronized, the lock will be
on the class not on object.

Problem without static synchronization
• Suppose there are two objects of a shared class (e.g. Table)
named object1 and object2.
• In case of synchronized method and synchronized block there
cannot be interference between t1 and t2 or t3 and t4 because
t1 and t2 both refers to a common object that have a single
lock.
• But there can be interference between t1 and t3 or t2 and t4
because t1 acquires another lock and t3 acquires another lock.
• We don't want interference between t1 and t3 or t2 and t4.
Static synchronization solves this problem.
Example of Static Synchronization
• TestSynchronization4.java
Deadlock in Java
• Deadlock in Java is a part of multithreading.
• Deadlock can occur in a situation 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 first thread.
• Since, both threads are waiting for each other to release the lock, the
condition is called deadlock.
Example of Deadlock in Java
• TestDeadlockExample1.java
More Complicated Deadlocks
• Thread 1 locks A, waits for B
• Thread 2 locks B, waits for C
• Thread 3 locks C, waits for D
• Thread 4 locks D, waits for A
• Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3
waits for thread 4, and thread 4 waits for thread 1.
How to Avoid Deadlock in Java?
1.Avoid Nested Locks: We must avoid giving locks to multiple threads, this
is the main reason for a deadlock condition. It normally happens when you
give locks to multiple threads.
2.Avoid Unnecessary Locks: The locks should be given to the important
threads. Giving locks to the unnecessary threads that cause the deadlock
condition.
3.Using Thread Join: A deadlock usually happens when one thread is
waiting for the other to finish. In this case, we can use join with a
maximum time that a thread will take.
Inter-thread Communication in Java
• Inter-thread communication or Co-operation is all about
allowing synchronized threads to communicate with each other.
• Cooperation (Inter-thread communication) is a mechanism in
which a thread is paused running in its critical section and
another thread is allowed to enter (or lock) in the same critical
section to be executed.
• It is implemented by following methods of Object class:
• wait()
• notify()
• notifyAll()
wait() method, notify() method, notifyAll() method

• The wait() method causes current thread to release the lock and wait
until either another thread invokes the notify() method or the
notifyAll() method for this object, or a specified amount of time has
elapsed.
• The current thread must own this object's monitor, so it must be
called from the synchronized method only otherwise it will throw
exception.
• The notify() method wakes up a single thread that is waiting on this
object's monitor.
• If any threads are waiting on this object, one of them is chosen to be
awakened.
• The choice is arbitrary and occurs at the discretion of the
implementation.
Example of Inter Thread Communication
in Java
• Test.java
Producer-Consumer problem
• The Producer-Consumer problem is a classical multi-process
synchronization problem, that is we are trying to achieve
synchronization between more than one process.
• There is one Producer in the producer-consumer problem, Producer
is producing some items, whereas there is one Consumer that is
consuming the items produced by the Producer.
• The same memory buffer is shared by both producers and
consumers which is of fixed-size.
• The task of the Producer is to produce the item, put it into the
memory buffer, and again start producing items.
• Whereas the task of the Consumer is to consume the item from the
memory buffer.
Producer-Consumer problem: few points
• The producer should produce data only when the buffer is not
full. In case it is found that the buffer is full, the producer is not
allowed to store any data into the memory buffer.
• Data can only be consumed by the consumer if and only if the
memory buffer is not empty. In case it is found that the buffer is
empty, the consumer is not allowed to use any data from the
memory buffer.
• Accessing memory buffer should not be allowed to producer
and consumer at the same time.
Producer-Consumer problem: Solution
• The producer is to either go to sleep or discard data if the buffer is full.
• The next time the consumer removes an item from the buffer, it notifies
the producer, who starts to fill the buffer again.
• In the same manner, the consumer can go to sleep if it finds the buffer
to be empty.
• The next time the producer puts data into the buffer, it wakes up the
sleeping consumer.

You might also like