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

Thread

Uploaded by

abhiraj90577
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)
16 views

Thread

Uploaded by

abhiraj90577
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/ 22

Topic –Exception Handling

Multithreading in Java
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


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:
o Process-based Multitasking (Multiprocessing)
o Thread-based Multitasking (Multithreading)
1) Process-based Multitasking (Multiprocessing)
o Each process has an address in memory. In other words, each process allocates a separate memory area.
o A process is heavyweight.
o Cost of communication between the process is high.
o Switching from one process to another requires some time for saving and loading registers, memory
maps, updating lists, etc.
2) Thread-based Multitasking (Multithreading)
o Threads share the same address space.
o A thread is lightweight.
o Cost of communication between the thread is low.
Note: At least one process is required for each thread.

1
Topic –Exception Handling

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.

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

2
Topic –Exception Handling

o 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. Each
and every thread runs for a short span of time and when that allocated time slice is over, the thread
voluntarily gives up the CPU to the other thread, so that the other threads can also run for their slice of
time. Whenever such a scenario occurs, all those threads that are willing to run, waiting for their turn to
run, lie in the runnable state. In the runnable state, there is a queue where the threads lie.
o 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.

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.
For example, a thread (let's say its name is A) may want to print some data from the printer. However, at the
same time, the other thread (let's say its name is B) is using the printer to print some data. Therefore, thread A
has to wait for thread B to use the printer. Thus, thread A is in the blocked state. A thread in the blocked state is
unable to perform any execution and thus never consume any cycle of the Central Processing Unit (CPU). Hence,
we can say that thread A remains idle until the thread scheduler reactivates thread A, which is in the waiting or
blocked state.
When the main thread invokes the join() method then, it is said that the main thread is in the waiting state. The
main thread then waits for the child threads to complete their tasks. When the child threads complete their job, a
notification is sent to the main thread, which again moves the thread from waiting to the active 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.

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

3
Topic –Exception Handling

in the timed wait state. After the time runs out, the thread wakes up and start its execution from when it has left
earlier.
Terminated: A thread reaches the termination state because of the following reasons:
o When a thread has finished its job, then it exists or terminates normally.
o 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.
The following diagram shows the different states involved in the life cycle of a thread.

Creating 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.Thread class extends
Object class and implements Runnable interface.
Commonly used Constructors of Thread class:

4
Topic –Exception Handling

o Thread()
o Thread(String name)
o Thread(Runnable r)
o 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.
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 thread(depricated).
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.

5
Topic –Exception Handling

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().
1. 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:
o A new thread starts(with new callstack).
o The thread moves from New state to the Runnable state.
o When the thread gets a chance to execute, its target run() method will run.

1) 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..
.
2) Java Thread Example by implementing Runnable interface
FileName: Multi3.java
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
}

6
Topic –Exception Handling

public static void main(String args[]){


Multi3 m1=new Multi3();
Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
t1.start();
}
}
Output:
thread is running...
If you are not extending the Thread class, your class object would not be treated as a thread object. So you need
to explicitly create the Thread class object. We are passing the object of your class that implements Runnable so
that your class run() method may execute.

3) Using the Thread Class: Thread(String Name)


We can directly use the Thread class to spawn new threads using the constructors defined above.
FileName: MyThread1.java
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

7
Topic –Exception Handling

4) Using the Thread Class: Thread(Runnable r, String name)

FileName: MyThread2.java
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 name)
Thread th1 = new Thread(r1, "My new thread");
// the start() method moves the thread to the active state
th1.start();

// getting the thread name by invoking the getName() method


String str = th1.getName();
System.out.println(str);
}
}
Output:
My new thread
Now the thread is running ...

8
Topic –Exception Handling

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 some criteria that decide which thread will execute first. 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.

First Come First Serve Scheduling:


In this scheduling algorithm, the scheduler picks the threads thar arrive first in the runnable queue. Observe the
following table:

Threads Time of Arrival

t1 0

t2 1

t3 2

t4 3

In the above table, we can see that Thread t1 has arrived first, then Thread t2, then t3, and at last t4, and the order
in which the threads will be processed is according to the time of arrival of threads.

Hence, Thread t1 will be processed first, and Thread t4 will be processed last.

9
Topic –Exception Handling

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.

In the above diagram, each thread is given a time slice of 2 seconds. Thus, after 2 seconds, the first thread leaves
the CPU, and the CPU is then captured by Thread2. The same process repeats for the other threads too.

10
Topic –Exception Handling

Preemptive-Priority Scheduling:
The name of the scheduling algorithm denotes that the algorithm is related to the priority of the threads.

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.
Working of the Java Thread Scheduler

11
Topic –Exception Handling

Let's understand the working of the Java thread scheduler. Suppose, there are five threads that have different
arrival times and different priorities. Now, it is the responsibility of the thread scheduler to decide which thread
will get the CPU first.
The thread scheduler selects the thread that has the highest priority, and the thread begins the execution of the
job. If a thread is already in runnable state and another thread (that has higher priority) reaches in the runnable
state, then the current thread is pre-empted from the processor, and the arrived thread with higher priority gets
the CPU time.
When two threads (Thread 2 and Thread 3) having the same priorities and arrival time, the scheduling will be
decided on the basis of FCFS algorithm. Thus, the thread that arrives first gets the opportunity to execute first.

// Java Program to Illustrate Priorities in Multithreading


// via help of getPriority() and setPriority() method

// Importing required classes


import java.lang.*;
// Main class
class ThreadDemo extends Thread
{
// Method 1
// run() method for the thread that is called
// as soon as start() is invoked for thread in main()
public void run()
{
// Print statement
System.out.println("Inside run method");
}
// Main driver method
public static void main(String[] args)
{
// Creating random threads
// with the help of above class

12
Topic –Exception Handling

ThreadDemo t1 = new ThreadDemo();


ThreadDemo t2 = new ThreadDemo();
ThreadDemo t3 = new ThreadDemo();

// Thread 1
// Display the priority of above thread
// using getPriority() method
System.out.println("t1 thread priority : " + t1.getPriority());

// Thread 1
// Display the priority of above thread
System.out.println("t2 thread priority : " + t2.getPriority());

// Thread 3
System.out.println("t3 thread priority : " + t3.getPriority());

// Setting priorities of above threads by


// passing integer arguments
t1.setPriority(2);
t2.setPriority(5);
t3.setPriority(8);

// t3.setPriority(21); will throw


// IllegalArgumentException
// 2
System.out.println("t1 thread priority : " + t1.getPriority());
// 5
System.out.println("t2 thread priority : " + t2.getPriority());

// 8

13
Topic –Exception Handling

System.out.println("t3 thread priority : " + t3.getPriority());

// Main thread
// Displays the name of
// currently executing Thread
System.out.println(
"Currently Executing Thread : "+ Thread.currentThread().getName());

System.out.println(
"Main thread priority : " + Thread.currentThread().getPriority());

// Main thread priority is set to 10


Thread.currentThread().setPriority(10);

System.out.println(
"Main thread priority : "+ Thread.currentThread().getPriority());
}
}

Output
t1 thread priority : 5
t2 thread priority : 5
t3 thread priority : 5
t1 thread priority : 2
t2 thread priority : 5
t3 thread priority : 8
Currently Executing Thread : main
Main thread priority : 5
Main thread priority : 10

14
Topic –Exception Handling

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:
Following are the syntax of the sleep() method.
1. public static void sleep(long mls) throws InterruptedException
2. public static void sleep(long mls, int n) throws InterruptedException
The method sleep() with the one parameter is the native method, and the implementation of the native method is
accomplished in another programming language. The other methods having the two parameters are not the native
method. That is, its implementation is accomplished in Java. We can access the sleep() methods with the help of
the Thread class, as the signature of the sleep() methods contain the static keyword. The native, as well as the
non-native method, throw a checked Exception. Therefore, either try-catch block or the throws keyword can
work here.
The Thread.sleep() method can be used with any thread. It means any other thread or the main thread can invoke
the sleep() method.
Parameters:
The following are the parameters used in the sleep() method.
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.
The method does not return anything.

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.

15
Topic –Exception Handling

The following example shows how one can use the sleep() method on the custom thread.
FileName: TestSleepMethod1.java
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);
}
System.out.println(i);
}
}
public static void main(String args[])
{
TestSleepMethod1 t1=new TestSleepMethod1();
TestSleepMethod1 t2=new TestSleepMethod1();
t1.start();
t2.start();
}
}
Output:
1
1
2
2
3
3
4
4

16
Topic –Exception Handling

As you know well that at a time only one thread is executed. If you sleep a thread for the specified time, the
thread scheduler picks up another thread and so on.

Example of the sleep() Method in Java: When the sleeping time is -ive
The following example throws the exception IllegalArguementException when the time for sleeping is negative.
FileName: TestSleepMethod2.java
// important import statements
import java.lang.Thread;
import java.io.*;

public class TestSleepMethod2


{
// main method
public static void main(String argvs[])
{
// we can also use throws keyword followed by
// exception name for throwing the exception
try
{
for (int j = 0; j < 5; j++)
{
// it throws the exception IllegalArgumentException
// as the time is -ive which is -100
Thread.sleep(-100);
// displaying the variable's value
System.out.println(j);
}
}
catch (Exception expn)
{

// the exception iscaught here


System.out.println(expn);
}
}
}
Output:
java.lang.IllegalArgumentException: timeout value is negative

17
Topic –Exception Handling

Synchronization in Java
Synchronization in Java threads is a mechanism used to control access to shared resources in a multi-threaded
environment. Without synchronization, when multiple threads try to modify the same shared resource
simultaneously, it can lead to inconsistent data or unpredictable behavior. Java provides synchronization to
ensure that only one thread can access a critical section (a part of the code that modifies shared resources) at a
time.
Why use Synchronization?
The synchronization is mainly used to
1. To prevent thread interference.
2. To prevent consistency problem.
Thread Synchronization
It can be achieved by using the following three ways:
1. By Using Synchronized Method
2. By Using Synchronized Block
3. By Using Static Synchronization
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.

1. Synchronized Methods: You can declare a method as synchronized using the synchronized keyword.
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock (also called
monitor lock) of the object. Other threads trying to access any synchronized method on the same object
will be blocked until the lock is released.
class Counter
{
private int count = 0;
public synchronized void increment()
{
count++;
}
public int getCount()
{

18
Topic –Exception Handling

return count;
}
}
2. Synchronized Block: Instead of synchronizing an entire method, you can synchronize only a portion of
it using a synchronized block. This can improve performance because the lock is held for a shorter period.

class Counter
{
private int count = 0;
public void increment()
{
synchronized (this)
{
count++;
}
}
public int getCount()
{
return count;
}
}
Here, this refers to the current object, and the lock is acquired only for the block of code within the synchronized
block.
3. Static Synchronization: If you declare a static method as synchronized, the lock will be on the class
object, rather than on the instance of the class.
class Counter
{
private static int count = 0;
public static synchronized void increment()
{
count++;
}

public static int getCount()


{
return count;
}
}
4. Deadlock: Improper use of synchronization can lead to deadlock, where two or more threads are waiting
for each other to release locks, and none of them can proceed. Proper design is necessary to avoid
deadlocks in a multi-threaded environment.

19
Topic –Exception Handling

Daemon thread
A daemon thread in Java is a special type of thread that runs in the background and performs tasks such as
garbage collection, memory management, or other housekeeping activities. Daemon threads are low-priority
threads and are designed to support non-critical tasks within the application.
One of the key characteristics of daemon threads is that they do not prevent the JVM from exiting. When all user
threads (non-daemon threads) finish executing, the JVM will terminate, regardless of whether daemon threads
are still running.

Characteristics of Daemon Threads:


 Background threads: They run in the background and typically perform tasks that are not crucial for
the application to complete, like garbage collection.
 Do not block JVM exit: When only daemon threads remain, the JVM will exit. This is different from
user threads, where the JVM will wait for all user threads to finish before exiting.
 Low-priority: Daemon threads typically have lower priority than user threads.
Setting a Daemon Thread
You can set a thread as a daemon thread by using the setDaemon(true) method before the thread starts. By
default, threads are user threads unless specified otherwise.

class DaemonExample extends Thread


{
public void run()
{
if (Thread.currentThread().isDaemon())
{
System.out.println("This is a daemon thread.");
}
else
{
System.out.println("This is a user thread.");
}
}
public static void main(String[] args)
{
DaemonExample t1 = new DaemonExample(); // User thread by default

20
Topic –Exception Handling

DaemonExample t2 = new DaemonExample(); // Will set to daemon


DaemonExample t3 = new DaemonExample(); // User thread by default
// Setting t2 as a daemon thread
t2.setDaemon(true);

// Start threads
t1.start(); // User thread
t2.start(); // Daemon thread
t3.start(); // User thread
}
}
Output:
This is a user thread.
This is a daemon thread.
This is a user thread.
Important Notes:
1. setDaemon(true) must be called before the thread is started. If you try to set a thread as daemon after
starting it, you will get an IllegalThreadStateException.
2. JVM exits when only daemon threads are running. If all non-daemon threads (user threads) complete,
the JVM will terminate, even if daemon threads are still running.
3. Use cases: Daemon threads are useful for tasks like monitoring, cleanup, or performing periodic
background tasks without requiring the program to wait for them to finish.

Example to Show JVM Exit Behavior:


Here's an example demonstrating how daemon threads allow the JVM to exit while user threads do not:

class DaemonExample extends Thread


{
public void run()
{
try
{
for (int i = 1; i <= 5; i++)
{
System.out.println(Thread.currentThread().getName() + " - Count: " + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)

21
Topic –Exception Handling

{
System.out.println("Thread interrupted");
}
}

public static void main(String[] args)


{
DaemonExample t1 = new DaemonExample(); // User thread
DaemonExample t2 = new DaemonExample(); // Will set to daemon
// Set t2 as daemon
t2.setDaemon(true);
// Start both threads
t1.start(); // User thread
t2.start(); // Daemon thread
}
}
In this example:
 t1 is a user thread and will run its entire loop.
 t2 is a daemon thread, and it will stop running when the JVM exits after t1 completes. If the sleep()
duration is long, you may notice that t2 will not complete its entire loop.
Expected Output:
Thread-0 - Count: 1
Thread-1 - Count: 1
Thread-0 - Count: 2
Thread-1 - Count: 2
Thread-0 - Count: 3
Thread-0 - Count: 4
Thread-0 - Count: 5
You may notice that Thread-1 (the daemon thread) stops counting after Thread-0 (the user thread) finishes its
execution, because the JVM exits once the user thread completes.

22

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy