Multithreading.
Multitasking:
Executing several tasks simultaneously is a concept of multitasking.
There are two types of multitasking
1. Process-based multitasking
2. Thread based multitasking
Process based Multitasking:
Executing several tasks simultaneously where each task is a separate independent program(process) is called
Process based Multitasking.
Example: while typing a java program in the editor, we can listen audio songs from the same system at the
same time we can download a file from the net. All these tasks will be executed simultaneously and
independent of each other.
- Hence it is process based multitasking.
- Process based multitasking is best suitable at OS level.
Thread Based Multitasking:
Executing several tasks simultaneously where each task is separate independent part of the same program
is called Thread based Multitasking and each independent part is called a Thread.
Thread based Multitasking is best suitable at Programmatic level.
Whether it is Process based or Thread based the main objective of multitasking is to reduce response
time of the system and to improve performance.
The main important application areas of multithreading are
- To develop multimedia graphics.
- To develop animations.
- To develop video games.
- To develop web servers and applications servers etc.
Thread:
Thread is a flow/Process of execution or light weight process.
Defining a Thread:
We can define a thread in the following two ways
- By extending Thread class
- By implementing Runnable interface
By Extending Thread class:
Case 1: Thread Schedular:
It is the part of JVM and it is responsible to schedule Threads i.e., if multiple threads are waiting to get the chance of execution, then in which order threads will be executed is decided by Thread Schedular.
- We can't expect exact algorithm followed by thread schedular and it is varied from JVM to JVM.
- Hence, we can't expect thread execution order and exact output.
- Hence whenever situation comes to multithreading there is no guarantee for exact output, but we can provide several possible outputs.
The following are various possible outputs for the above program
Possibility-1 | Possibility-2 | Possibility-3 | Possibility-4 |
---|---|---|---|
Main Thread | Child Thread | Main Thread | Child Thread |
Main Thread | Child Thread | Child Thread | Main Thread |
Main Thread | Child Thread | Main Thread | Child Thread |
Main Thread | Child Thread | Child Thread | Main Thread |
Main Thread | Child Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Child Thread | Main Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Child Thread | Main Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Case 2: Difference between t.start() and t.run()
In the case of t.start(), a new Thread will be created which is responsible for the execution of run() method.
But, in this case of t.run() a new Thread won't be created and the run() method will be executed by just like a normal method call by main Thread.
Hence in the above if we replace t.start() with t.run()
It is executed by only Main Thread and the Output for above program is
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Case 3: Importance of Thread class start() method
- Thread class start() method is responsible to register the Thread with Thread Schedular and all other mandatory activities.
- Hence without executing Thread class start() method there is no chance of starting a new Thread in Java.
- Due to this, Thread class start() method is considered as heart of multithreading
start(){
1.Register this thread with Thread Schedular;
2.Perform all other mandatory activities;
3.Invoke run();
}
Case 4: Overloading of run() method
Overloading of run() method is always possible but Thread class start() method can invoke no-args method.
The other overloaded run() method we have to call explicitly like a normal method call.
Output:
no-args run
Case 5: If we are not Overriding run() method
If we are not Overriding run() method then Thread class run() method will be executed which has empty implementation. Hence, we won't get any output.
Output:
no OUTPUT
NOTE: It is highly recommended to override run() method, otherwise don't go for Multithreading concept.
Case 6: Overriding of start() method
If we override start() method, then our start() method will be executed just like a normal method call and new Thread won't be created.
Output:
start method
main method
NOTE: It is not recommended to override start() method. Otherwise, don't go for Multithreading concept.
Case 7:
The following are various possible outputs for the above program
Possibility-1 | Possibility-2 | Possibility-3 |
---|---|---|
run method | start method | start method |
start method | main method | run method |
main method | run method | main method |
Case 8: Thread Life Cycle
Case 9:
After starting a Thread, if we are trying to restart the same thread then we will get runtime exception saying IllegalThreadStateException.
Output:
main method
run method
2. Defining a Thread by implementing Runnable Interface:
We can define a thread by implementing Runnable interface
1st Approach: MyThread ---------> Thread ------> Runnable(I)
2nd Approach: MyRunnable ----------------------> Runnable(I)
Runnable(I) present in java.lang package and it contains only one method i.e., run() method.
We will get mixed output and we can't tell exact output.
The following are various possible outputs for the above program
Possibility-1 | Possibility-2 | Possibility-3 | Possibility-4 |
---|---|---|---|
Main Thread | Child Thread | Main Thread | Child Thread |
Main Thread | Child Thread | Child Thread | Main Thread |
Main Thread | Child Thread | Main Thread | Child Thread |
Main Thread | Child Thread | Child Thread | Main Thread |
Main Thread | Child Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Child Thread | Main Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Child Thread | Main Thread | Main Thread | Child Thread |
Child Thread | Main Thread | Child Thread | Main Thread |
Case Study:
Case 1: t1.start()
A new Thread will be created and which is responsible for the execution of Thread class run() method, which has empty implementation.
Case 2: t1.run()
No new Thread will be created and Thread class run() method will be executed just like a normal method call.
Case 3: t2.start()
A new Thread will be created which is responsible for the execution of MyRunnable class run() method.
Case 4: t2.run()
A new Thread won't be created and MyRunnable class run() method will be executed just like a normal method call.
Case 5: r.start()
we will get compile time error saying MyRunnable class doesn't have start() capability.
C-Error: Cannot find symbol method start() location class MyRunnable
Case 6: r.run()
No new Thread will be created and MyRunnable class run() method will be executed like normal method call.
Which approach is best to define a Thread?
- Among two ways of defining a Thread, implements Runnable approach is recommended
- In the first approach, our class always extends Thread class, there is no chance of extending any other class. Hence, we are missing inheritance benefit.
- But in the second approach, while implementing Runnable interface, we can extends any other class. Hence, we won't miss any inheritance benefit.
- Because of above reason implementing Runnable interface approach is recommended than extending Thread class.
Thread Class Constructors:
Approach to define a Thread (Not Recommended to use):
Output:
Possibility1 | Possibility2 |
---|---|
child thread | main thread |
main thread | child thread |
Getting and Setting name of a Thread:
Every Thread in java has same name, it may be default name generated by JVM or customised name provided by programmer.
We can get and set name of a Thread by using the following two methods of Thread class
Output:
main
Thread-0
ProgrammingWithKalyan
NOTE: We can get current executing Thread object by using Thread.currentThread() method
Output:
run method executed by Thread Thread-0
main method executed by Thread main
0 Comments