KEMBAR78
Multi Threading | PDF | Process (Computing) | Thread (Computing)
0% found this document useful (0 votes)
7 views19 pages

Multi Threading

Threads in Java are lightweight processes that enable effective multitasking by allowing concurrent execution of parts of a program. They can be created by extending the Thread class or implementing the Runnable interface, and they operate within various states throughout their lifecycle. The advantages of multithreading include non-blocking user experience, time savings through concurrent operations, and independence of threads to handle exceptions without affecting others.
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)
7 views19 pages

Multi Threading

Threads in Java are lightweight processes that enable effective multitasking by allowing concurrent execution of parts of a program. They can be created by extending the Thread class or implementing the Runnable interface, and they operate within various states throughout their lifecycle. The advantages of multithreading include non-blocking user experience, time savings through concurrent operations, and independence of threads to handle exceptions without affecting others.
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/ 19

Why Threads are used?

Now, we can understand why threads are being used as they had the advantage of
being lightweight and can provide communication between multiple threads at a Low
Cost contributing to effective multi-tasking within a shared memory environment.

What is Main Thread?

As we are familiar, we create Main Method in each and every Java Program, which acts
as an entry point for the code to get executed by JVM, Similarly in this Multithreading
Concept, Each Program has one Main Thread which was provided by default by JVM,
hence whenever a program is being created in java, JVM provides the Main Thread for its
Execution.

How to Create Threads using Java Programming Language?

We can create Threads in java using two ways, namely :

1. Extending Thread Class

2. Implementing a Runnable interface

Multithreading in Java
Multithreading is a Java feature that allows concurrent execution of two or more parts of
a program for maximum utilization of CPU. Each part of such program is called a thread.
So, threads are light-weight processes within a process.

Threads can be created by using two mechanisms :

1. Extending the Thread class

2. Implementing the Runnable Interface


Advantages of Java Multithreading

1) It doesn't block the user because threads are independent and you can perform multiple
operations at the same time.

2) You can perform many operations together, so it saves time.

3) 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.


Thread Class

A Thread class has several methods and constructors which allow us to perform
various operations on a thread. The Thread class extends the Object class. The
Object class implements the Runnable interface. The thread class has the
following constructors that are used to perform various operations.

○ Thread()
○ Thread(Runnable, String name)
○ Thread(Runnable target)
○ Thread(ThreadGroup group, Runnable target, String name)
○ Thread(ThreadGroup group, Runnable target)
○ Thread(ThreadGroup group, String name)
○ Thread(ThreadGroup group, Runnable target, String name, long
stackSize)

Commonly used methods of Thread class:

1. public void run(): is used to perform action for a thread.

2. public void start(): starts the execution of the thread.JVM calls the run() method on
the thread.

3. public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.

4. public void join(): waits for a thread to die.

5. public void join(long miliseconds): waits for a thread to die for the specified
miliseconds.

6. public int getPriority(): returns the priority of the thread.

7. public int setPriority(int priority): changes the priority of the thread.

8. public String getName(): returns the name of the thread.

9. public void setName(String name): changes the name of the thread.

10. public Thread currentThread(): returns the reference of currently executing thread.
11. public int getId(): returns the id of the thread.

12. public Thread.State getState(): returns the state of the thread.

13. public boolean isAlive(): tests if the thread is alive.

14. public void yield(): causes the currently executing thread object to temporarily pause
and allow other threads to execute.

15. public void suspend(): is used to suspend the thread(depricated).

16. public void resume(): is used to resume the suspended thread(depricated).

17. public void stop(): is used to stop the thread(depricated).

18. public boolean isDaemon(): tests if the thread is a daemon thread.

19. public void setDaemon(boolean b): marks the thread as daemon or user thread.

20. public void interrupt(): interrupts the thread.

21. public boolean isInterrupted(): tests if the thread has been interrupted.

22. public static boolean interrupted(): tests if the current thread has been interrupted.

Thread creation by
extending the Thread class
We create a class that extends the java.lang.Thread class. This class overrides the run()
method available in the Thread class. A thread begins its life inside run() method. We create
an object of our new class and call start() method to start the execution of a thread. Start()
invokes the run() method on the Thread object.

Example:
class MultithreadingDemo extends Thread {
public void run()
{
try {
// Displaying the thread that is running
System.out.println(
"Thread Name: "+Thread.currentThread().getName()+
" Thread Id: " + Thread.currentThread().getId() + " is running");
}
catch (Exception e) {
// Throwing an exception
System.out.println("Exception is caught");
}
}
}

// Main Class
public class Main {
public static void main(String[] args)
{
int n = 5; // Number of threads
for (int i = 0; i < n; i++) {
MultithreadingDemo object = new MultithreadingDemo();
object.start();
}
}
} Output:

Thread creation by implementing the Runnable Interface


We create a new class which implements java.lang.Runnable interface and override run()
method. Then we instantiate a Thread object and call start() method on this object.

Steps to create a new thread using Runnable

1. Create a Runnable implementer and implement the run() method.

2. Instantiate the Thread class and pass the implementer to the Thread, Thread has a

constructor which accepts Runnable instances.

3. Invoke start() of Thread instance, start internally calls run() of the implementer. Invoking
start() creates a new Thread that executes the code written in run(). Calling run()
directly doesn’t create and start a new Thread, it will run in the same thread. To start a
new line of execution, call start() on the thread.

Example:
class MultithreadingDemo implements Runnable {
public void run()
{
try {
// Displaying the thread that is running
System.out.println(
"Thread Name: "+Thread.currentThread().getName()+
" Thread Id: " + Thread.currentThread().getId() + " is running");
}
catch (Exception e) {
// Throwing an exception
System.out.println("Exception is caught");
}
}
}
// Main Class
public class Main {
public static void main(String[] args)
{
int n = 5; // Number of threads
for (int i = 0; i < n; i++) {
Thread object = new Thread(new MultithreadingDemo());
object.start();
}
}
}

Thread Class vs Runnable Interface

1. If we extend the Thread class, our class cannot extend any other class because

Java doesn’t support multiple inheritance. But, if we implement the Runnable

interface, our class can still extend other base classes.

2. We can achieve basic functionality of a thread by extending Thread class

because it provides some inbuilt methods like yield(), interrupt() etc. that are

not available in Runnable interface.

3. Using runnable will give you an object that can be shared amongst multiple

threads.
Lifecycle and States of a Thread in Java
A thread in Java at any point of time exists in any one of the following states. A
thread lies only in one of the shown states at any instant:
1. New State

2. Runnable State

3. Blocked State

4. Waiting State

5. Timed Waiting State

6. Terminated State

The diagram shown below represents various states of a thread at any instant in

time.
Life Cycle of a Thread
There are multiple states of the thread in a lifecycle as mentioned below:

1. New Thread: When a new thread is created, it is in the new state. The thread has not
yet started to run when the thread is in this state. When a thread lies in the new state,
its code is yet to be run and hasn’t started to execute.

2. Runnable State: A thread that is ready to run is moved to a runnable state. In this
state, a thread might actually be running or it might be ready to run at any instant of
time. It is the responsibility of the thread scheduler to give the thread, time to run.
A multi-threaded program allocates a fixed amount of time to each individual thread.
Each and every thread runs for a short while and then pauses and relinquishes the
CPU to another thread so that other threads can get a chance to run. When this
happens, all such threads that are ready to run, waiting for the CPU and the currently
running thread lie in a runnable state.

3. Blocked: The thread will be in blocked state when it is trying to acquire a lock but
currently the lock is acquired by the other thread. The thread will move from the
blocked state to runnable state when it acquires the lock.

4. Waiting state: The thread will be in waiting state when it calls wait() method or join()
method. It will move to the runnable state when other thread will notify or that thread
will be terminated.

5. Timed Waiting: A thread lies in a timed waiting state when it calls a method with a
time-out parameter. A thread lies in this state until the timeout is completed or until a
notification is received. For example, when a thread calls sleep or a conditional wait, it
is moved to a timed waiting state.

6. Terminated State: A thread terminates because of either of the following reasons:

● Because it exits normally. This happens when the code of the thread has been entirely
executed by the program.
● Because there occurred some unusual erroneous event, like a segmentation fault or an
unhandled exception.

yield() method:
A yield() method is a static method of Thread class and it can stop the currently executing
thread and will give a chance to other waiting threads of the same priority. If in case there
are no waiting threads or if all the waiting threads have low priority then the same thread
will continue its execution.
The advantage of yield() method is to get a chance to execute other waiting threads so if
our current thread takes more time to execute and allocate processor to other threads.
yield() vs wait()

● While yield() is invoked in the context of the current thread, wait() can only
be invoked on an explicitly acquired lock inside a synchronized block or
method
● Unlike yield(), it is possible for wait() to specify a minimum time period to
wait before any attempt to schedule the thread again
● With wait() it is also possible to wake the thread anytime through an
invocation of notify() or notifyAll() on the concerned lock object

yield() vs sleep()

● While yield() can only make a heuristic attempt to suspend the execution of
the current thread with no guarantee of when will it be scheduled back,
sleep() can force the scheduler to suspend the execution of the current
thread for at least the mentioned time period as its parameter.

yield() vs join()
● The current thread can invoke join() on any other thread which makes the
current thread wait for the other thread to die before proceeding
● Optionally it can mention a time period as its parameter which indicates the
maximum time for which the current thread should wait before resuming

Usage for yield()

As the official documentation suggests it’s rarely necessary to use yield() and
hence should be avoided unless very clear with the objectives in the light of its
behavior.

Nonetheless, some of use for yield() include designing concurrency control


constructs, improving system responsiveness in a compute-heavy program etc.

However, these usages must be accompanied by detailed profiling and


benchmarking to ensure the desired outcome.

Example

class MyThread extends Thread {


public void run() {
for (int i = 0; i < 5; ++i) {
Thread.yield();
System.out.println("Thread started:" + Thread.currentThread().getName());
}
System.out.println("Thread ended:" + Thread.currentThread().getName());
}
}
class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
for (int i = 0; i < 5; ++i) {
System.out.println("Thread started:" + Thread.currentThread().getName());
}
System.out.println("Thread ended:" + Thread.currentThread().getName());
}
}

Output:
Thread started:Thread-0 Thread started:main
Thread started:main Thread started:main
Thread started:Thread-0 Thread ended:Thread-0
Thread started:Thread-0 Thread ended:main
Thread started:main
Thread started:Thread-0
Thread started:Thread-0
Thread started:main

Difference between Wait, Sleep, Join and Yield in Java


Let us see a comparison between yield(), join() and sleep() methods.

Property yield() join() sleep()

Purpose We use yield(), if a We use join()method sleep() method is used


thread is willing to when a thread is if a thread does not
pass its execution (set willing to wait until want to perform
its status back to the completion of a operation for a definite
Ready state) to give a different thread. amount of time.
chance to other
remaining threads in
the ready state.

Is it No Yes Yes
overloaded?

Is it final? No Yes No
Static method? Yes No Yes

Throws No Yes Yes


exception?

Priority of a Thread (Thread Priority)

Each thread has a priority. Priorities are represented by a number between 1 and 10. In
most cases, the thread scheduler schedules the threads according to their priority (known
as preemptive scheduling). But it is not guaranteed because it depends on JVM
specification that which scheduling it chooses. Note that not only JVM a Java programmer
can also assign the priorities of a thread explicitly in a Java program.

● The default priority is set to 5 as excepted.

● Minimum priority is set to 1.

● Maximum priority is set to 10.

Here 3 constants are defined in it namely as follows:

1. public static int NORM_PRIORITY

2. public static int MIN_PRIORITY

3. public static int MAX_PRIORITY

Setter & Getter Method of Thread Priority

Let's discuss the setter and getter method of the thread priority.

public final int getPriority(): The java.lang.Thread.getPriority() method returns the


priority of the given thread.

public final void setPriority(int newPriority): The java.lang.Thread.setPriority() method


updates or assign the priority of the thread to newPriority. The method throws
IllegalArgumentException if the value newPriority goes out of the range, which is 1
(minimum) to 10 (maximum).

Example 1:

Output:
Thread Running...
max thread priority : 10
min thread priority : 1
normal thread priority : 5

Example 2:
// Importing the required classes
import java.lang.*;

public class ThreadPriorityExample extends Thread


{
// Method 1
// Whenever the start() method is called by a thread
// the run() method is invoked
public void run()
{
// the print statement
System.out.println("Inside the run() method");
}
// the main method
public static void main(String argvs[])
{
// Creating threads with the help of ThreadPriorityExample class
ThreadPriorityExample th1 = new ThreadPriorityExample();
ThreadPriorityExample th2 = new ThreadPriorityExample();
ThreadPriorityExample th3 = new ThreadPriorityExample();
// We did not mention the priority of the thread.
// Therefore, the priorities of the thread is 5, the default value
// 1st Thread
// Displaying the priority of the thread
// using the getPriority() method
System.out.println("Priority of the thread th1 is : " + th1.getPriority());
// 2nd Thread
// Display the priority of the thread
System.out.println("Priority of the thread th2 is : " + th2.getPriority());
// 3rd Thread
// // Display the priority of the thread
System.out.println("Priority of the thread th2 is : " + th2.getPriority());
// Setting priorities of above threads by
// passing integer arguments
th1.setPriority(6);
th2.setPriority(3);
th3.setPriority(9);
// 6
System.out.println("Priority of the thread th1 is : " + th1.getPriority());
// 3
System.out.println("Priority of the thread th2 is : " + th2.getPriority());
// 9
System.out.println("Priority of the thread th3 is : " + th3.getPriority());
// Main thread
// Displaying name of the currently executing thread
System.out.println("Currently Executing The Thread : " + Thread.currentThread().getName());
System.out.println("Priority of the main thread is : " + Thread.currentThread().getPriority());
// Priority of the main thread is 10 now
Thread.currentThread().setPriority(10);
System.out.println("Priority of the main thread is : " + Thread.currentThread().getPriority());
}
}

Output:
Priority of the thread th1 is : 5
Priority of the thread th2 is : 5
Priority of the thread th2 is : 5
Priority of the thread th1 is : 6
Priority of the thread th2 is : 3
Priority of the thread th3 is : 9
Currently Executing The Thread : main
Priority of the main thread is : 5
Priority of the main thread is : 10

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?


Java Synchronization is used to make sure by some synchronization method that
only one thread can access the resource at a given point in time.

When we start two or more threads within a program, there may be a situation
when multiple threads try to access the same resource and finally they can
produce unforeseen result due to concurrency issues. For example, if multiple
threads try to write within a same file then they may corrupt the data because one
of the threads can override data or while one thread is opening the same file at the
same time another thread might be closing the same file.
So there is a need to synchronize the action of multiple threads and make sure
that only one thread can access the resource at a given point in time. This is
implemented using a concept called monitors. Each object in Java is associated
with a monitor, which a thread can lock or unlock. Only one thread at a time may
hold a lock on a monitor.

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

1. Process Synchronization

2. Thread Synchronization

1. Process Synchronization in Java

Process Synchronization is a technique used to coordinate the execution of


multiple processes. It ensures that the shared resources are safe and in order.

2. Thread Synchronization in Java

Thread Synchronization is used to coordinate and ordering of the execution of the


threads in a multi-threaded program. There are two types of thread
synchronization are mentioned below:

● Mutual Exclusive

● Cooperation (Inter-thread communication in Java)

Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while
sharing data. There are three types of Mutual Exclusive mentioned below:

● Synchronized method.

● Synchronized block.

● Static synchronization.

A. Synchronized Method

We can declare a method as synchronized using the “synchronized” keyword.


This will make the code written inside the method thread-safe so that no other
thread will execute while the resource is shared.

B. Synchronized Block

If we declare a block as synchronized, only the code which is written inside that
block is executed sequentially not the complete code. This is used when we want
sequential access to some part of code or to synchronize some part of code.

C. Static Synchronization

In this, the synchronized method is declared as “static” which means the lock or
monitor is applied on the class not on the object so that only one thread will
access the class at a time.

You might also like