Multi-threading refers to the concurrent execution of multiple threads within the
Thread
A thread is the smallest unit of execution within a process, and multithreading allows multiple threads to execute concurrently, sharing the same resources such as memory space, file handles, and other process-wide resources.
How to create a thread in java ?
We can create our custom thread by two methods
By extending Thread class
By implementing Runnable interface
Creating a thread by extending Thread class
We define our custom thread class
MyThread
which extendsThread
ClassIn
MyThread
Class we overriderun
method ,which contains the code that the thread will execute when startedIn the
Main
class, we create an instance ofMyThread
and start it using thestart()
method.We can execute our task defined in the run method by either calling
start()
or by usingrun()
method the main difference is that if we userun()
then a new thread will not be created.
class MyThread extends Thread {
// Override the run() method to define the code that the thread will execute
@Override
public void run() {
// Code inside this method will be executed when the thread starts
for (int i = 0; i < 5; i++) {
System.out.println("Thread running: " + i);
try {
// Introduce a short delay to simulate some work being done
Thread.sleep(1000); // Sleep for 1 second (1000 milliseconds)
} catch (InterruptedException e) {
// Handle the InterruptedException if needed
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
// Create an instance of your custom thread class
MyThread myThread = new MyThread();
// Start the thread
myThread.start();
// The code below will continue to execute
//immediately after starting the thread
// It will not wait for the thread to finish its execution
System.out.println("Main thread exiting...");
}
}
Output
Creating a thread by implementing Runnable interface
Creating a thread by implementing the Runnable
interface is a common practice in Java and provides more flexibility compared to extending the Thread
class
We define a class
MyRunnable
that implements theRunnable
interface.Inside
MyRunnable
, we implement therun()
method, which contains the code that the thread will execute when started.In the
Main
class, we create an instance ofMyRunnable
We then create a
Thread
object, passing theMyRunnable
instance as a parameter to its constructorNow
start()
method ofThread
object begins the execution of the thread, and therun()
method ofMyRunnable
will be executed concurrently within thisThread
along with the main thread.
// Define a class that implements the Runnable interface
class MyRunnable implements Runnable {
// Implement the run() method defined by the Runnable interface
@Override
public void run() {
// Code inside this method will be executed when the thread starts
for (int i = 0; i < 5; i++) {
System.out.println("Thread running: " + i);
try {
// Introduce a short delay to simulate some work being done
Thread.sleep(1000); // Sleep for 1 second (1000 milliseconds)
} catch (InterruptedException e) {
// Handle the InterruptedException if needed
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
// Create an instance of your custom Runnable class
MyRunnable myRunnable = new MyRunnable();
// Create a Thread object, passing the Runnable instance as a parameter
Thread thread = new Thread(myRunnable);
// Start the thread
thread.start();
// It will not wait for the thread to finish its execution
System.out.println("Main thread exiting...");
}
}
Output
Various Constructors of Thread class
Java provides various contructors of thread class for various usecases
Thread()
This constructor creates a new thread object.
The thread's runnable target is set to null, meaning it does not have a target to execute.
You would typically subclass (basically extending Thread class)
Thread
and override itsrun()
method to define the thread's behavior before starting it.
Thread(Runnable target)
This constructor creates a new thread object with the specified
Runnable
target.The
Runnable
target represents the task that the thread will execute when started.You pass an instance of a class that implements the
Runnable
interface, providing therun()
method implementation as the target for the thread.
Thread(Runnable target, String name)
This constructor creates a new thread object with the specified
Runnable
target and name.The
name
parameter allows you to give the thread a meaningful name for identification and debugging purposes.This is useful when working with multiple threads to distinguish them in logs or thread dumps.
Thread (ThreadGroup group, Runnable target)
This constructor creates a new thread object with the specified
ThreadGroup
andRunnable
target.The
ThreadGroup
parameter allows you to specify the thread group to which the new thread belongs.A thread group in Java is a way to group multiple threads together for easier management and control. It provides a mechanism for organizing threads into a hierarchical structure, allowing you to perform operations on multiple threads collectively
Thread(ThreadGroup group, Runnable target, String name)
This constructor creates a new thread object with the specified
ThreadGroup
,Runnable
target, and name.It combines the functionalities of the previous two constructors, allowing you to specify both the thread group and the name of the thread.
And also giving your own runnable target.
Lifecycle of a thread
A thread passes through various stages during it's lifetime from creation to termination . Various stages in a lifecycle of a thread are
New (or Born)
A thread enters the new state when an instance of the Thread
class is created but has not yet been started by invoking its start()
method.
Runnable (or Ready)
Once the
start()
method is called on a thread, it enters the runnable state.Now the thread is ready to be executed but it's on thread scheduler to when execute it
In this state, the thread may be executing if the scheduler has allocated CPU time to it, or it may be waiting for CPU time.
Running State
When the scheduler selects the thread from the runnable state, it enters the running state.
The thread's
run()
method is being executed, and it is actively using CPU resources.Only one thread can be in the running state at any given time on a single CPU core.
Blocked (or Waiting) State
A thread enters the blocked state when it is temporarily unable to proceed with its execution, typically because it's waiting for a resource or condition to become available.
For example, a thread might enter a blocked state when waiting for I/O operations to complete, waiting to acquire a lock, or waiting on a condition variable , or waiting for other thread to complete it's execution.
The thread remains in this state until the condition it's waiting for is satisfied.
Timed Waiting State
Threads can also enter a timed waiting state, which is similar to the blocked state but with a timeout.
This state occurs when a thread invokes methods like
Thread.sleep()
,Object.wait()
, orThread.join()
with a specified timeout.The thread remains in this state until either the specified time elapses or the condition it's waiting for is satisfied.
Terminated (or Dead) State
A thread enters the terminated state when its
run()
method completes, or when it is explicitly terminated by callingThread.stop()
(not recommended) or when an uncaught exception terminates the thread.Once a thread is terminated, it cannot be restarted.
After termination, a thread can be garbage collected.
Methods for pausing the execution of a thread
yield()
join()
sleep()
This was the overview of multithreading in java , in the next post we will talk more about these methods of a Thread class and synchronization.
Thank you , Have a nice day ๐
Bye Bye๐โโ๏ธ see you all in the next post.