The mechanism of
executing multiple threads simultaneously is known as multithreading. A thread
is a sequence of method calls within the program. Every thread is independent
and has its program counter, stack and local variable. In this tutorial, I am
going to cover all the concepts that are related to threads. We will cover what
are threads, Why do we need multithreading, how can we create threads, what is
the concept of threads, examples of multithreading in java.
What are the threads?
A Thread is a lightweight
process. They allow multiple tasks to be performed at the same time. All the
threads share the same address space. Since they share the same address they
can have common data and code.
What is the difference between threads and process?
1. A Thread is a part of a process whereas a
process is defined as a program in execution.
2. Each thread has its stack. Multiple threads
share the same address space of process whereas process has its address space.
3. Threads are lightweight whereas processes are
heavyweight
4. As threads are lightweight they have less
overhead as compared to the process.
5. For communication process uses Interprocess
communication whereas threads can communicate directly as they share the same
address.
The life cycle of a
thread
A thread goes through different stages during its life cycle. The below diagram shows different stages of the cycle.
Let us discuss these:
1. New - this stage is also referred to as a born stage.
This is the initial stage wherein a thread is created and will remain in this
thread until the program starts it.
2. Runnable - This stage comes when a thread starts its execution. This
stage comes when we call start().
3. Running - this stage comes when the thread scheduler selects the
thread. run() invokes this stage.
4. Waiting - from the running stage while the thread is running if we
can sleep() or wait() methods then this stage comes into the picture.
5. Dead - this stage comes when the thread execution is completed.
This stage is also known as the terminated stage.
Thread
priorities
To make the multiple
threads run in order the OS scheduler needs to divide the multiple threads
based on thread priority. Hence, to achieve this each thread is assigned with
its priority.
The range of priority is
defined by three variables i.e. MIN_PRIORITY, a constant of 1, MAX_PRIORITY, a
constant of 10 and NORM_PRIORITY, a constant of 5. By default, NORM_PRIORITY is
declared for every thread.
The threads which have
higher priority will be scheduled first as compared to lower priority threads.
However, the priority of a thread is not the sole reason for thread execution,
the operating system also plays a very big role.
How
to create a thread in java
There are mainly two
ways by which we can create a thread.
1. Implementing the runnable interface
2. Extending the thread class
There is a significant
difference in when to use which method. Consider the scenario in which the
class is already extending another class and as java does not support multiple
inheritance hence we will not be allowed to create a thread by extending the
class. Hence, in cases when the class is extending another class, we can create
a thread by implementing the runnable interface.
Also, if we know that
the class implementation is full and in future also we will not be extending
this class with another class then we can create the thread by extending the
thread class otherwise, we should implement the runnable interface.
Let’s discuss both these
ways in detail with an example:
Creating
thread by Implementing a runnable interface
Steps need to be
followed to create a thread using the runnable interface.
1. The runnable interface has run() method
which we need to implement into the class. This will create an entry point for
the thread. All the main logic which requires threading will be under this
method.
2. In the second step, we need to create the object
of the thread class using its default constructor
Thread(Runnable
Obj, String threadName)
The
obj should be the instance of the class which implements the runnable
interface.
- As
the last step, after the thread object is created, we need to call start() method
on the object of the runnable class. This will internally call the run() method.
Below is the example of creating and running a thread.
Output:
Creating Stage Thread t1
Starting stage Thread t1
Creating Stage Thread t2
Starting stage Thread t2
Running Stage Thread t1
Thread: Thread t1,
4
Running Stage Thread t2
Thread: Thread t2,
4
Thread: Thread t1,
3
Thread: Thread t2,
3
Thread: Thread t1,
2
Thread: Thread t2,
2
Thread: Thread t1,
1
Thread: Thread t2,
1
Thread t1 exiting
Thread t2 exiting
Creating
a thread by extending thread class
Steps need to be
followed to create a thread by extending thread class
1. Thread class has an abstract run() method
which we need to override into the class. This will create an entry point for
the thread. All the main logic which requires threading will be under this
method.
2. As the last step, after the thread object is
created, we need to call start() method on the object of the
runnable class. This will internally call the run() method.
Below is the example of creating and running a thread.
Output:
Creating Stage Thread t1
Starting stage Thread t1
Creating Stage Thread t2
Starting stage Thread t2
Running Stage Thread t1
Thread: Thread t1,
4
Running Stage Thread t2
Thread: Thread t2,
4
Thread: Thread t1,
3
Thread: Thread t2,
3
Thread: Thread t1,
2
Thread: Thread t2,
2
Thread: Thread t1,
1
Thread: Thread t2,
1
Thread Thread t1 exiting
Thread Thread t2 exiting
Important
Thread methods
Sr. No. |
Methods and Description |
1. |
public void start() |
2. |
public void run() |
3. |
public final void setName(String name) |
4. |
public final void setPriority(int priority) |
5. |
public final void setDeamon(boolean on) |
6. |
public final void join(long milisec |
7. |
public void interrupt() |
8. |
public final boolean isAlive() |
9. |
public static void yield() |
10. |
public static void sleep(long milisec) |
11. |
public static boolean holdsLock(Object x) |
12. |
public static Thread currentThread() |
13. |
public static void dumpStack() |
Inter-thread
Communication
Threads concept in java
provides a very seamless way so that threads can communicate with each other.
There can be scenarios where multiple threads want to share some information.
In this case, we need inter-thread communication.
Inter-thread
communication is also important to overcome Deadlock. Deadlock is the case when
multiple threads are waiting for the object access.
There are three methods
which facilitate inter-thread communication:
Sr. No. |
Methods and Description |
1. |
public void wait() |
2. |
public void notify() |
3. |
public void notifyAll() |
public void wait() -
takes the thread to wait for the state until notify() called.
public
void notify() - wakes the thread
on which wait() was called.
public
void notifyAll() - wakes all the
threads on which wait() was called.
All these methods are in
object class as they deal with objects and perform the operations on objects.
Hence, they are available in all the classes. Only synchronized context
can call these methods.
Let’s go through an example where two threads communicate with each other using wait() and notify().
Conclusion:
As we have seen the
importance of thread in java programming. Java threads come handy when we have
a multi-threaded environment. Helps to run the multiple processes at the
background.
Please feel free to add some points and also correct me if I am wrong at any point.
0 Comments