Unit - 4: Multithreading
Unit - 4: Multithreading
UNIT – 4
Multithreading
Multithreading: The Java thread model, Creating threads, Thread priorities,
Synchronizing threads, Interthread communication.
INTRODUCTION
The Java run-time system depends on threads for many things, and all the class
libraries are designed with multithreading.
In fact, Java uses threads to enable the entire environment to be asynchronous. This
helps reduce inefficiency by preventing the waste of CPU cycles.
Java thread models are
o Single thread system
o Multithread system
Single thread System
Single-threaded systems use an approach called an event loop with polling.
In this model, a single thread of control runs in an infinite loop, polling a single event
queue to decide what to do next.
Once this polling mechanism returns with, say, a signal that a network file is ready to
be read, then the event loop dispatches control to the appropriate event handler.
Until this event handler returns, nothing else can happen in the system. This wastes
CPU time.
It can also result in one part of a program dominating the system and preventing any
other events from being processed.
In general, in a singled-threaded environment, when a thread blocks (that is, suspends
execution) because it is waiting for some resource, the entire program stops running.
Multithread system
The benefit of Java’s multithreading is that the main loop/polling mechanism is
eliminated.
One thread can pause without stopping other parts of program.
For example, the idle time created when a thread reads data from a network or waits
for user input can be utilized elsewhere.
Multithreading allows animation loops to sleep for a second between each frame
without causing the whole system to pause.
When a thread blocks in a Java program, only the single thread that is blocked pauses.
All other threads continue to run.
All runnable threads are in a queue and wait for CPU access. When the start () method is
called on the newborn thread, it will be in the runnable state. It is not in the running state yet
because system resources such as the CPU (which might be serving another thread at that
point) are not available.
• If a thread is waiting for the completion of an input or output operation, then the operation
must finish.
CREATING THREADS
In java, a thread is a lightweight process. Every java program executes by a thread called the
main thread. When a java program gets executed, the main thread created automatically. All
other threads called from the main thread.
The java programming language provides two methods to create threads, and they are listed
below.
1. Using Thread class (by extending Thread class)
2. Using Runnable interface (by implementing Runnable interface)
The java contains a built-in class Thread inside the java.lang package. The Thread class
contains all the methods that are related to the threads.
To create a thread using Thread class, follow the step given below.
Step-1: Create a class as a child of Thread class. That means, create a class that
extends Thread class.
Step-2: Override the run( ) method with the code that is to be executed by the thread.
The run( ) method must be public while overriding.
Step-3: Create the object of the newly created class in the main( ) method.
Step-4: Call the start( ) method on the object created in the above step.
Example
class SampleThread extends Thread{
}
}
The java contains a built-in interface Runnable inside the java.lang package. The Runnable
interface implemented by the Thread class that contains all the methods that are related to the
threads.
To create a thread using Runnable interface, follow the step given below.
Step-1: Create a class that implements Runnable interface.
Step-2: Override the run( ) method with the code that is to be executed by the thread.
The run( ) method must be public while overriding.
Step-3: Create the object of the newly created class in the main( ) method.
Step-4: Create the Thread class object by passing above created object as parameter
to the Thread class constructor.
Step-5: Call the start( ) method on the Thread class object created in the above step.
Example
The Thread class in java is a subclass of Object class and it implements Runnable interface.
The Thread class is available inside the java.lang package. The Thread class has the
following syntax.
sleep( long ) moves the thread to blocked state till the specified void
number of milliseconds.
THREAD PRIORITIES
Java assigns to each thread a priority that determines how that thread should be
treated with respect to the others.
Thread priorities are integers that specify the relative priority of one thread to another.
As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run
any faster than a lower-priority thread if it is the only thread running.
Instead, a thread’s priority is used to decide when to switch from one running thread
to the next. This is called a context switch.
Every Java thread has a priority that helps the operating system determine the order in
which threads are scheduled.
Java thread priorities are in the range between MIN_PRIORITY (a constant of 1) and
MAX_PRIORITY (a constant of 10). By default, every thread is given priority
NORM_PRIORITY (a constant of 5).
Threads with higher priority are more important to a program and should be allocated
processor time before lower-priority threads.
However, thread priorities cannot guarantee the order in which threads execute and
are very much platform dependent.
The rules that determine when a context switch takes place are simple:
o A thread can voluntarily relinquish control. This is done by explicitly yielding,
sleeping, or blocking on pending I/O. In this scenario, all other threads are
examined, and the highest-priority thread that is ready to run is given the CPU.
o A thread can be preempted by a higher-priority thread. In this case, a lower-
priority thread that does not yield the processor is simply preempted—no
matter what it is doing— by a higher-priority thread. Basically, as soon as a
higher-priority thread wants to run, it does. This is called preemptive
multitasking.
In cases where two threads with the same priority are competing for CPU cycles, the
situation is a bit complicated.
o For windows - round-robin fashion,
o For other types of operating systems, threads of equal priority must voluntarily
yield control to their peers
Daemon Thread
Daemon thread is the low priority thread which runs in the background to perform
garbage collection.
It always depends on user threads.
JVM does not have control over daemon thread. It can keep running even when the
program has stopped.
Output:
Daemon Thread
User Thread
User Thread
SYNCHRONIZATION
The java programming language supports multithreading. The problem of shared resources
occurs when two or more threads get execute at the same time. In such a situation, we need
some way to ensure that the shared resource will be accessed by only one thread at a time,
and this is performed by using the concept called synchronization.
In java, the synchronization is achieved using the following concepts.
1. Mutual Exclusion
2. Inter thread communication
Mutual Exclusion
Using the mutual exclusion process, we keep threads from interfering with one
another while they accessing the shared resource. In java, mutual exclusion is achieved using
the following concepts.
Synchronized method
Synchronized block
Synchronized method
When a method created using a synchronized keyword, it allows only one object to access it
at a time. When an object calls a synchronized method, it put a lock on that method so that
other objects or thread that are trying to call the same method must wait, until the lock is
released. Once the lock is released on the shared resource, one of the threads among the
waiting threads will be allocated to the shared resource.
In the above image, initially the thread-1 is accessing the synchronized method and other
threads (thread-2, thread-3, and thread-4) are waiting for the resource (synchronized method).
When thread-1 completes it task, then one of the threads that are waiting is allocated with the
synchronized method, in the above it is thread-3.
Example
class Table{
synchronized void printTable(int n) {
for(int i = 1; i <= 10; i++)
System.out.println(n + " * " + i + " = " + i*n);
}
}
class MyThread_1 extends Thread{
Table table = new Table();
int number;
MyThread_1(Table table, int number){
this.table = table;
this.number = number;
}
public void run() {
table.printTable(number);
}
}
class MyThread_2 extends Thread{
Table table = new Table();
int number;
MyThread_2(Table table, int number){
this.table = table;
this.number = number;
}
public void run() {
table.printTable(number);
}
}
public class ThreadSynchronizationExample {
Synchronized block
The synchronized block is used when we want to synchronize only a specific sequence of
lines in a method. For example, let's consider a method with 20 lines of code where we want
to synchronize only a sequence of 5 lines code, we use the synchronized block.
Syntax
synchronized(object)
{
...
block code
...
}
Example
import java.util.*;
class NameList {
String name = "";
public int count = 0;
namesList_2.addName("Seetha", list);
System.out.println("Thread1: " + namesList_1.name + ", " + namesList_1.getCount() +
"\n");
System.out.println("Thread2: " + namesList_2.name + ", " + namesList_2.getCount() +
"\n");
}
}
INTERTHREAD COMMUNICATION
Inter thread communication is the concept where two or more threads communicate to solve
the problem of polling. In java, polling is the situation to check some condition repeatedly, to
take appropriate action, once the condition is true. That means, in inter-thread
communication, a thread waits until a condition becomes true such that other threads can
execute its task. The inter-thread communication allows the synchronized threads to
communicate with each other.
wait( )
notify( )
notifyAll( )
The following table gives detailed description about the above methods.
Method Description
void wait( ) It makes the current thread to pause its execution until other thread in the
same monitor calls notify( )
void notify( ) It wakes up the thread that called wait( ) on the same object.
void notifyAll() It wakes up all the threads that called wait( ) on the same object.
Let's look at an example problem of producer and consumer. The producer produces the item
and the consumer consumes the same. But here, the consumer cannot consume until the
producer produces the item, and producer cannot produce until the consumer consumes the
item that already been produced. So here, the consumer has to wait until the producer
produces the item, and the producer also needs to wait until the consumer consumes the
same. Here we use the inter-thread communication to implement the producer and consumer
problem.
Example
class ItemQueue {
int item;
boolean valueSet = false;
{
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Consummed:" + item);
valueSet = false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
notify();
return item;
}
notify();
}
}
ItemQueue itemQueue;
Consumer(ItemQueue itemQueue){
this.itemQueue = itemQueue;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
itemQueue.getItem();
}
}
}
class ProducerConsumer{
public static void main(String args[]) {
ItemQueue itemQueue = new ItemQueue();
new Producer(itemQueue);
new Consumer(itemQueue);
}
}