Object-Oriented Programming with JAVA: BCS306A
MODULE V
MODULE V
Multithreaded Programming
The Java Thread Model
The Main Thread,
Creating a Thread, Creating Multiple Threads,
Using isAlive() and join()
Thread Priorities, Synchronization, Interthread Communication,
Suspending, Resuming, and Stopping Threads
Obtaining a Thread’s State.
Enumerations
Type Wrappers and Autoboxing - Enumerations (Enumeration Fundamentals,
The values() and value Of() Methods),
Type Wrappers (Character, Boolean, The Numeric Type Wrappers),
Autoboxing - Autoboxing and Methods, Autoboxing/Unboxing Occurs in
Expressions, Autoboxing/Unboxing Boolean and Character Values
Understanding Multithreading
Multithreading is a programming concept in which the application can create a small
unit of tasks to execute in parallel. If you are working on a computer, it runs multiple
applications and allocates processing power to them. A simple program runs in sequence and
the code statements execute one by one. This is a single-threaded application. But, if the
programming language supports creating multiple threads and passes them to the operating
system to run in parallel, it’s called multithreading.
How does Java Support Multithreading?
Java has great support for multithreaded applications. Java supports multithreading
through the Thread class. Java Thread allows us to create a lightweight process that executes
some tasks. We can create multiple threads in our program and start them. Java runtime will
take care of creating machine-level instructions and work with OS to execute them in parallel.
How to create a thread in Java
There are two ways to create a thread:
1. By extending the Thread class
2. By implementing a Runnable interface.
The Thread class defines several methods that help manage Threads. Several of these
are
Department of Artificial Intelligence & Data Science, DBIT
1
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Method Meaning
getName() Returns this thread’s name
getPriority() Returns this thread’s priority
run() If this thread was constructed using a separate Runnable run
object, then that Runnable object’s run method is called;
otherwise, this method does nothing and returns
join() Waits for this thread to die
start() Causes this thread to begin execution; the Java Virtual Machine
calls the run method of this thread
sleep suspend a thread for some time
Java Thread Priority in Multithreading
As we already know java being completely object-oriented works within
a multithreading environment in which the thread scheduler assigns the processor to a thread
based on the priority of the 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 the programmer explicitly.
Priorities in threads is a concept where each thread has a priority which in layman’s
language one can say every object has priority here which is represented by numbers
ranging from 1 to 10.
The Main Thread
When a Java program starts, one thread begins running immediately. This is usually
called the main thread of your program, because it is the one that executed when your
program begins. The main thread is important for two reasons
It is the thread from which other child threads will be spawned.
Often, it must be the last thread to finish execution because it performs various
shutdown actions.
Demonstration of Main Thread, Child Thread and the Methods in Thread Class
available in Built in Thread Class
public class DemonstrationOfBuitInMethods {
public static void main(String[] args) {
Thread t = [Link]();
[Link]("The Current Thread is "+ [Link]());
Department of Artificial Intelligence & Data Science, DBIT
2
Object-Oriented Programming with JAVA: BCS306A
MODULE V
[Link]("MYTHREAD");
[Link]("The Thread name after changing is "+
[Link]());
[Link]("The Thread priority is "+
[Link]());
[Link](5);
[Link](Thread.MIN_PRIORITY);
[Link]("The Thread priority is "+
[Link]());
ChildThread ct=new ChildThread();
[Link]();
[Link]("The ChildThread priority is
"+[Link]());
}
}
public class ChildThread extends Thread {
public void run() {
for(int i=1; i<=5;i++) {
[Link]("Child Thread is Running");
}
}
A Closer Look at the Program
Created a class called DemonstrationOfBuitInMethods
Thread which is running is called the main
[Link]() will tell us what is the thread name
[Link]() will tell us the priority order.
We also have the option to set the priority as minimum with the code
Thread.MIN_PRIORITY
A class ChildThread is created and defined a method called run()
ChildThread ct=new ChildThread() will create a thread object
[Link]() will make the thread into action.
[Link]
[Link]
UvZVJH8&index=3
[Link] – In Tamil – Explaining CPU
utilization
NOTE: press Shift + control + esc, we can see the performance of the system.
Department of Artificial Intelligence & Data Science, DBIT
3
Object-Oriented Programming with JAVA: BCS306A
MODULE V
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). Now, we will learn methods of creating
multiple threads in Java program. 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.
Demonstration of Creation of Multiple Threads
public class Thread1 extends Thread {
public void run() {
for(int i=1; i<=5; i++){
[Link]("Thread1 " + (i*2));
}
[Link]("Exiting Thread1");
}
}
public class Thread2 extends Thread{
public void run() {
for(int i=1; i<=5; i++) {
[Link]("Thread2 " + (i*5));
}
[Link]("Exiting from Thread2 “);
}
}
public class Thread3 extends Thread {
public void run() {
for(int i=1; i<=5; i++) {
[Link]("Thread2 " + (i*10));
}
[Link]("Exiting from Thread3 ");
}
}
public class MultiThreadDemo {
public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread2 t2=new Thread2();
Department of Artificial Intelligence & Data Science, DBIT
4
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Thread3 t3=new Thread3();
[Link]();
[Link]();
[Link]();
}
}
A Closer Look at the Program
Created 3 classes which is an extension of Thread Class, Thread1, Thread2 and
Thread3
All the three classes perform three different task using overriding method run()
In the class called MultiThreadDemo, we have created objects for all the three classes
[Link](), [Link]() and [Link]() initiate the three threads
So, in the MultiThreadDemo class there are four threads one is main thread and
another three child threads all will run concurrently
Runnable Interface
The Thread class and the Runnable interface are integral to Java’s multithreading
capabilities, each offering unique advantages and use cases. Developers must carefully
consider their application requirements and design preferences when choosing between the
two.
While Thread provides a straightforward mechanism for creating and managing
threads, it comes with limitations due to Java’s single inheritance constraint. On the other
hand, Runnable promotes better object-oriented design, reusability, and resource sharing,
making it a preferred choice in many scenarios. A nuanced understanding of the differences
between Thread and Runnable empowers developers to make informed decisions when
designing concurrent applications in Java, ensuring efficiency, maintainability, and scalability
in the world of multithreading.
[Link] – Runnable Interface – Tamil
[Link] – Runnable Interface
Department of Artificial Intelligence & Data Science, DBIT
5
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Thread vs. Runnable
o There are several differences between Thread class and Runnable interface based on
their performance, memory usage, and composition. By extending thread, there is
overhead of additional methods, i.e. they consume excess or indirect memory,
computation time, or other resources.
o Since in Java, we can only extend one class, and therefore if we extend Thread class,
then we will not be able to extend any other class. That is why we should implement
Runnable interface to create a thread.
o Runnable makes the code more flexible as, if we are extending a thread, then our code
will only be in a thread whereas, in case of runnable, one can pass it in various
executor services, or pass it to the single-threaded environment.
o Maintenance of the code is easy if we implement the Runnable interface.
Demonstration of Runnable Interface
public class A implements Runnable {
public void run() {
for(int i=0; i<=5; i++) {
[Link](i);
}
}
public class STR {
public static void main(String[] args) {
A obj = new A();
Thread t= new Thread(obj);
[Link]();
for(int i=0; i<=5; i++) {
[Link](" Hai");
Department of Artificial Intelligence & Data Science, DBIT
6
Object-Oriented Programming with JAVA: BCS306A
MODULE V
}
}
}
A Closer Look at the Program
class A is created with a runnable interface with the keyword implements
Runnable is having only one overriding method called run
The class STR is having two threads, one is main thread and another one is child
thread.
Main thread will create an object for the class A and also it will implement its own
method printing of Hai 5 times.
Object reference should be passed while creating the thread
Keyword - isAlive in Java
In the world of Java programming, developers often encounter scenarios where they
need to determine the status of a thread. Understanding whether a thread is alive or
has completed its execution is crucial for efficient thread management. In such
situations, the isAlive() method comes to the rescue. The isAlive() method is a built-
in method provided by the Thread class in Java. It allows developers to determine
whether a thread has terminated or is still executing. The method returns a Boolean
value indicating the status of the thread.
[Link]
Working of the isAlive() Method
When a thread completes its execution or is terminated, it automatically enters the
"dead" state. Prior to that, when a thread is created but not yet started, or when it is in the
middle of execution, it is considered "alive." The isAlive() method determines the status of a
thread by checking if it is alive or dead. It returns true if the thread is still alive and false if it
has completed execution.
Utilizing the isAlive() Method
Thread Status Monitoring
The primary purpose of the isAlive() method is to check the status of a thread during
runtime. By periodically invoking this method, developers can monitor the progress of a
thread and make decisions based on its status. For example, if a thread is performing a time-
consuming task, other threads can wait until it completes by checking its status using
isAlive().
Department of Artificial Intelligence & Data Science, DBIT
7
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Thread Synchronization
Thread synchronization is crucial in multithreaded environments to prevent race
conditions and ensure data integrity. The isAlive() method can be employed in
synchronization scenarios to control the execution flow. By checking the status of a particular
thread using isAlive(), other threads can pause or continue execution based on the desired
synchronization logic.
Thread Termination Handling
When a thread completes its execution or needs to be terminated prematurely, the
isAlive() method can be used to determine if the thread is still running. By continuously
invoking isAlive() until it returns false, you can ensure that the thread has indeed terminated
before proceeding with subsequent actions.
Thread Joining
The isAlive() method works in tandem with the join() method, which allows one
thread to wait for the completion of another. By invoking isAlive() on a target thread and
subsequently calling join(), a waiting thread can be sure that the target thread has completed
its execution before proceeding further.
Demonstration of Thread Synchronization
Consider the idea that two different teams have created 1000 cakes by each team, we
want to count all these cake. So Team1 and Team2 will be sharing the same counter to count
the cakes. If both the team count together, even though there are two cakes at the same time,
but count will be only one, so that at last there will be a mismatch in the total number of
cakes. So the idea is both of them should not count together. To incorporate this we use the
keyword synchronized prior to the void function name.
public class CakeCounter {
int cakecount=0;
public synchronized void increment() {
cakecount++;
}
}
public class Team implements Runnable{
CakeCounter counter;
Team(CakeCounter counter){
[Link]=counter;
}
public void run() {
for (int i=0; i<1000; i++) {
Department of Artificial Intelligence & Data Science, DBIT
8
Object-Oriented Programming with JAVA: BCS306A
MODULE V
[Link]();
}
}
}
public class Synchronisation {
public static void main(String[] args) {
CakeCounter counter = new CakeCounter();
Thread Team1 = new Thread(new Team(counter));
Thread Team2 = new Thread(new Team(counter));
[Link]();
[Link]();
try {
[Link]();
[Link]();
}
catch(Exception e) {
}
[Link]([Link]);
}
}
A Closer Look at The program
class CakeCounter is the class with a Synchronized function called increment()
class Team implements Runnable interface to do multithreading Tak
Using CakeCounter counter , we have created a reference variable for the class
CakeCounter in the class Team
Team(CakeCounter counter) is the constructor for the class team, passing object as
the parameter from the user
Using the overriding method run(), available in the Runnable interface, we are doing
the counting
In class Synchronisation, we have created the object for the class cakecounter and
also created the thread for the class Team.
Java join() method in Threads
Department of Artificial Intelligence & Data Science, DBIT
9
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Java Thread suspend() method
The suspend() method of thread class puts the thread from running to waiting state.
This method is used if you want to stop the thread execution and start it again when a certain
event occurs. This method allows a thread to temporarily cease execution. The suspended
thread can be resumed using the resume () method. Thread. suspend() is the code to suspend
the thread.
Java Thread stop() method
The stop() method of thread class terminates the thread execution. Once a thread is
stopped, it cannot be restarted by start() method. Thread. stop() is the code to stop the
thread.
Enumerations
Enum class is present in [Link] package. It is the common base class of all Java
language enumeration types. Enum, introduced in Java 5, is a special data type that consists
of a set of pre-defined named values separated by commas. These named values are also
known as elements or enumerators or Enum instances. Since the values in the Enum type are
constant, you should always represent them in UPPERCASE letters. You can use an Enum
type when you need a fixed set of pre-defined constant values that are known at the compile-
time itself. Examples can be days of the week, seasons of the year, etc.
The following characteristics make Enum a ‘special’ class:
Enum constants cannot be overridden
Enum doesn’t support the creation of objects
Enum can’t extend other classes
Enum can implement interfaces like classes
Why Do We Need Enumeration?
Java supports two types of Data Types:
1. User-Defined Datatypes
2. Inbuilt Data Types- int, float, double, char, etc.
Sometimes inbuilt data types are not sufficient. Let’s suppose that we have data of different
data types required to be stored in a single variable. In such a situation, inbuilt data types
won’t fulfil the need. That’s why there is a requirement for user-defined Data Types, and
Enum in Java is one of them.
[Link]
Department of Artificial Intelligence & Data Science, DBIT
10
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Demonstration of Enum Class
public enum DaysOfAWeek {
SUNDAY, MONDAY, TUESDAY,WEDNESDAY,THURSDAY, FRIDAY, SATURDAY;
}
public class Demo {
public static void main(String[] args) {
DaysOfAWeek day=[Link];
if (day==[Link]) {
[Link]("Hei, its almost weekend");
for (DaysOfAWeek myday: [Link]()) {
[Link](myday);
}
}
A Closer Look at The program
Enum class as Constructors
public enum Fruits {
APPLE(50),BANANA(30),ORANGE(60),GRAPES(90);
int delisiousness;
Fruits(int delisiousness){
[Link]=delisiousness;
}
}
public class Demo {
public static void main(String[] args) {
[Link]=109;
[Link]([Link]);
[Link]([Link]);
[Link] – ordinal
Department of Artificial Intelligence & Data Science, DBIT
11
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Wrapper classes in Java
The wrapper class in Java provides the mechanism to convert primitive into object
and object into primitive. Since J2SE 5.0, autoboxing and unboxing feature convert
primitives into objects and objects into primitives automatically. The automatic conversion of
primitive into an object is known as autoboxing and vice-versa unboxing.
Use of Wrapper classes in Java
Java is an object-oriented programming language, so we need to deal with objects
many times like in Collections, Serialization, Synchronization, etc. Let us see the different
scenarios, where we need to use the wrapper classes.
o Change the value in Method: Java supports only call by value. So, if we pass a
primitive value, it will not change the original value. But, if we convert the primitive
value in an object, it will change the original value.
o Serialization: We need to convert the objects into streams to perform the serialization.
If we have a primitive value, we can convert it into objects through the wrapper
classes.
o Synchronization: Java synchronization works with objects in Multithreading.
o [Link] package: The java. util package provides the utility classes to deal with
objects.
o Collection Framework: Java collection framework works with objects only. All
classes of the collection framework (ArrayList, LinkedList, Vector, HashSet,
LinkedHashSet, TreeSet, PriorityQueue, ArrayDeque, etc.) deal with objects only.
The eight classes of the [Link] package are known as wrapper classes in Java. The list of
eight wrapper classes are given below:
Department of Artificial Intelligence & Data Science, DBIT
12
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Autoboxing and Unboxing
Autoboxing is the automatic conversion that the Java compiler makes between
the primitive types and their corresponding object wrapper classes. For example,
converting an int to an Integer, a double to a Double, and so on.
Converting an object of a wrapper type (Integer) to its corresponding primitive
(int) value is called unboxing. The Java compiler applies unboxing when an object of
a wrapper class is: Passed as a parameter to a method that expects a value of the
corresponding primitive type.
Demonstration of Autoboxing and Unboxing
public class AutoBoxing {
public static void main(String[] args) {
int num=7;
@SuppressWarnings("removal")
Integer num1 = new Integer(8); /*This
code is correct.
We have made integer 8 as an object for
the wrapper class called Integer.
The line on the code shows that there
is a better way to do it.
Department of Artificial Intelligence & Data Science, DBIT
13
Object-Oriented Programming with JAVA: BCS306A
MODULE V
Here we have done it manually so Boxing
has been done*/
[Link](num1);
Integer num2=num;
/* Here at the compile time the int num
7 is converted to object of the
Integer Wrapper class automatically.
This is called auto Boxing */
[Link](num2);
int num3=num2;
[Link](num3); /* Here num2
is an object of the wrapper class.
we have converted the object into an
integer. That is Unboxing done */
String str="12" ;/* The number 12 is
saved as a string.
We want to do some calculation on this.
So we have to convert it into an int
data type*/
int num4 = [Link](str);
[Link](num4);
int b=20;
[Link](b+num4);
}
}
Department of Artificial Intelligence & Data Science, DBIT
14