A thread is a light-weight smallest part of a process that can run concurrently
with the other parts(other threads) of the same process.
Multithreading in Java is a process of executing multiple threads simultaneously. Multithreading,
used to achieve multitasking.
In java multithreading is used 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.
Multitasking is a process of executing multiple tasks simultaneously. We use
multitasking to utilize the CPU. Multitasking can be achieved in two ways:
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.
Threads share the same address space. A thread is lightweight.
Cost of communication between the thread is low.
New - Instance of thread created which is not yet started by involving
start(). In this state, the thread is also known as the born thread.
Runnable - After invocation of start() & before it is selected to be run by the scheduler.
Running - After the thread scheduler has selected it.
Non-runnable - thread alive, not eligible to run.
Terminated - run() method has exited.
A thread scheduler in java is the part of the JVM that decides which thread should
run and which should wait. The thread scheduler always chooses a thread to run only if it is in the
RUNNABLE state. But there is no guarantee which thread will be chosen to run if you have multiple
threads in RUNNABLE state.
There are a number of factor or criteria which are used to select a thread.
Priority
Whenever we create a thread, it always inherits priority from its parent thread. Each thread has a
priority that lies between 1 to 10. The higher priority of thread means a higher chance to get
selected for the execution.
Arrival time
The thread scheduler also depends on the arrival time of the thread. If two or more thread has same
priority then thread scheduler checks the arrival time of threads.
As you can see the name of the algorithm already says priority scheduling. This
algorithm is based on the priority of the thread. Suppose the multiple threads are in the RUNNABLE
state (ready to run), the thread scheduler chooses the threads that have the highest priority. It
will ignore the other’s thread and select the higher-priority thread.
1. A higher priority thread becomes runnable,
2. When the current thread goes for stop the execution. We can use yield(), sleep(), join()
method
to give the chance to executes the other threads.
3. If the selected thread has completed its time slice.
If any higher priority thread comes in the RUNNABLE state or the time slice of a given thread has
finished. Then the current running thread will be suspended and another thread having higher
priority will get time slice for completing its task in the Running state.
According to this algorithm, the thread scheduler assigns the CPU time to the thread which comes
first. The thread scheduler checks the arrival time of the thread, give the time slice for its
execution.
This algorithm based on First Comes First Serve and time slice. The thread scheduler assigns a piece
of time to each thread that is known as a time slice. The time slice is defined in the system and
every thread gets executed cyclically.
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.
Synchronized (Thread Safe) - Means one thread can access method at a time.
Non-synchronized (Not Thread Safe) - Means multiple thread can access the same method at the
same time.
Ways To Create A Thread In Java
- By extending the thread class
- By implementing Runnable interface
To create a thread using the thread class, we need to extend the thread class. Java's multithreading
system is based on the thread class.
class MyThread extends Thread{
@Override
public void run(){
int i =0;
while(i<40000){
System.out.println(" Thread is Running");
System.out.println("I am happy!");
i++;
}}
}
public class Main {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
}
}
To create a thread using the Runnable Interface, we need to implement the Runnable interface.
classs t1 implements Runnable{
@Override
public void run(){
System.out.println("Thread is running");
}
}
public class ClassName{
public static void main(String[] args) {
t1 obj1 = new t1();
Thread t = new Thread(obj1);
t.start();
}
}