Coding Guru
I.Multitasking
Executing multiple task simultaneously is called “Multitasking”.
There are two type of multitasking
-
Process based multitasking.
-
Thread based multitasking
II.Process based multitasking
-
Executing multiple tasks simultaneously, where each take is a separate independent process is called process based multitasking.
-
While typing a java program in editor we can able to listen music by media player from the machine. At the same time we can download a file from the net. All these tasks are executing separate and simultaneously and independent of each other. Hence it is process based multitasking.
-
Process based multitasking best suitable for O.S level
III.Thread based multitasking
-
Executing several task simultaneously where each task is a separate independent process of same program is called thread.
-
It is best suitable for the programming level.
-
Whether it is process based or thread based the main objective of this is to improve performance of the system by reducing the response time.
-
Main important usage of the multitasking is in video games, multi media graphics and animations.
IV.The ways to define, instantiate and start a new thread
We can define a thread in following two ways.
-
By extending Thread class
-
By implementing Runnable interface
A.Defining a thread by extending thread
Class Mythread extends Thread {
Public void run(){
For(int i=0; i< =10; i++){
s.o.p (“child thread”);
}
}
}
Class DemoThread {
Public static void main (String args[]){
MyThread t = new MyThread();
t.start();
for(int i=0; i< 10; i++){
s.o.p (“Main thread”);
}
}
}
B. Case 1 : Thread scheduler
-
Whenever multiple threads are waiting to get change for execution, which thread will execute first is decided by Thread scheduler, whose behavior is JVM vendor dependent. Hence we cannot expect exact execution order and hence exact o/p.
-
Thread scheduler is a part of JVM due to this unpredictable behavior of thread scheduler we cannot expect the exact o/p or execution order.
-
P1
Main thread
--
--
Child thread
--
--
- p2
Main thread
--
Child thread
--
Main thread
--
-Whenever the situation comes to multitasking the guarantee in behavior is very less. We can tell possible output but not exact o/p.
C.Case 2 : difference between t.start() and t.run()
-
In the case of t.start() a new thread will be created and thread is responsible to execute run().
-
But in the case of t. run() no new thread will be created and it will be executed as a normal method.
-
In the above program if we replace t.start() with t.run() the following is the o/p
Child thread
9 times
---
Main thread
9 times.
D.Case 3 : Importance of thread class start() method.
-
To start a thread class the required mandatory activities, like registering thread with thread scheduler will be performed automatically by thread class start() method.
-
Because of this facility programmer is not responsible to perform this activity and he is just responsible to define job of the thread.
-
Hence thread class start() method plays very important role and without executing that method there is no chance of starting a new thread.
Class Thread {
Start() {
-
Register this thread with threadScheduler & perform other initiation activities.
-
Run()
}
}
E.Case 4: 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 and hence we won’t get any output.
Eg.
Class MyThread extends Thread {
}
Class ThreadDemo {
Public s. v. main(String args[]){
MyThread t = new MyThread();
t.start();
}
}
No output o/p since it will execute Thread class run() method.
NOTE : it is highly recommended to override run() method it is our job.
F.Case 5 :overloading of run()
-
Overloading of run in possible but thread class start() will always call no arguments run() only.
-
But the other run() we have to call explicit just like a normal method call.
Class Mythread extends Thread
{
Public void run(){
s.o.p (“run executed”);
}
Public void run(int i){
s.o.p(“run with int parameter”);
}
}
Class MyThreadDemo {
Mythread t = new Mythread();
t.start();
}
0/p run executed.
G.Case 6: Overriding of start()
-
If we override start() method, thread class start() method will not be executed. It will treat as normal method call and no new thread will be created.
Eg :
Class MyThread extends Thread {
Public void start(){
Sop(“start executed”);
}
Public void run(){
Sop (“run method executed”);
}
}
Class MyThreadDemo {
MyThread t = new MyThread();
t.start();
}
o/p start executed.
H.Case 7
Public class MyThread extends Thread {
Public void start(){
Super.start();
Sysout(“start method called”);
}
Public void run(){
Sop (run methods called);
}
}
Public class MyThreadDemo {
MyThread t = new MyThread();
t.start();
sop (“main thread executed”);
}
Right o/p :
start method called
run method called
main thread called
right o/p
run method called
start method called
main thread called
wrong o/p
main thread called
run method called
start method called
I.Case 8 life cycle of thread
New / Born state
Ready / Runnable state
Running state
Dead state
Mythread t = new Mythread()
If thread scheduler allocate cpu
If run method completed
-
Once we create a new object then it is said to be New born state.
-
If we call start() then it thread will enter into the ready or runnable state.
-
If thread scheduler allocates cpu, then thread will enter into running state.
-
If run method completes then the thread will enter into the dead state.
J.Case 9
-
After stating the thread we are not allowed to restart the same thread again otherwise we will get RuntimeException saying IllegalThreadStateException.
Eg .
Thread t = new Thread();
t.start();
-
-
t.start() //illegalThreadStateException
-
Within the run() if we call super.start(), we will get same exception as above.
Note : Its never recommended to override start() method but recommended to override run().
V.Defining a thread by implementing “Runnable interface”.
-
We can define a thread even by implementing Runnable interface.
-
Runnable interface present in java.lang package and contains only one method run()
Runnable
Thread MyThread
MyThread
1st approach2nd approach
Eg.
Class MyRunnable implements Runnable {
Public void run(){
For(int I =0 ; I <10; i++){
Sop (“child thread”);
}
}
}
Class ThreadDemo {
P s v m (String args[]){
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
for(int i=0; i< 10; i++){
sop(“main thread”);
}
}
}
We cannot expect o/p and we will get mixed o/p
A.Case study
MyRunnab le r = new MyRunnable();
Thread t1 = new Thread();
Thead t2 = new Thread(r);
B.Case 1 t1.start()
-
A new thread will be created which is responsible for execution of thread class run()
C.Case 2 t1.run()
-
A new thread will not be created and thread class run() will execute as a normal method call.
D.Case 3 t2.start()
-
A new thread will be created which is responsible for execution of MyRunnable run() method.
E.Caset 4 t2.run()
-
A new thread will not be created and it will execute MyRunnable run() as a normal method call.
F.Case 5 r.start()
-
We will get compile time error saying start() is not available in MyRunnable class.
-
Cannot find symbol
G.Case 6 r.run()
-
No new thread will be created and MyRunnable run() will be called as a normal method call.
Q. In which of the above cases a new thread will be created.
T1.start() & t2.start()
Q. In which of the above cases MYRunnable class run() method will be called as a normal call.
t2.run() and r.run()
VI.Best approach to define a Thread
-
Among two ways of implementing thread, runnable interface is the best approach.
-
In the first approach we are extending Thread class and there is no room for extending another class. In the second approach we are implementing Runnable and there is a room for extending another class. So, we can say Runnable is the best approach.
VII.Thread class constructor
Thread t = new Thread();
Thread t = new Thread(Runnable r);
Thread t = new Thread(String str);
Thread t = new Thread(Runnable r, String str);
Thread t = new Thread(ThreadGroup t, string str);
Thread t = new Thread(ThreadGroup t , Runnable r);
Thread t = new Tread(ThreadGroup t, Runnable r, String str);
Thread t = new Thread(ThreadGroup t, Runnable r, String str, long StackSize);
VIII.Approach to define Thread (Not recommended to use)
Class MyThread extends Thread{
Public void run(){
Sop(“run method”);
}
}
Class Test {
P s v m(String args[]){
MyThread t = new MyThread();
Thread t = new Thread(t);
t.start();
sop (“main method”);
}
}
o/p
run method.
main method.
IX.Getting and Setting name of the Thread
-
Every thread in java has some name. It may be set my programmer or set by JVM.
-
We can get / set name of the thread by using following methods of the class.
-
Public final String getName()
-
Public final void setName(String name);
Class Threadexp {
P s v m (String args[]){
Sop (Thread.currentThread().getName());
Sop (Thread.currentThread().setName(“yeswanth”));
Sop(Thread.currentThread().getName());
}
}
// o/p Yeswanth
NOTE : we can get current thread executing Thread reference by using
Public static Thread currentThread();
X.Thread priority
-
Every thread in java has some priority but the range of the thread priority is 1 to 10 ( 1 is the least and 10 is the highest).
-
Thread class defines the following constants to define some standard priority.
-
Thread.MIN_PRIORITY 1
-
Thread.MAX_PRIORITY 10
-
Thread.NORM_PRORITY 2
-
Thread scheduler will use these priorities while allocating cpu.
-
The thread which is having highest priority will have highest priority.
-
If two threads have same priority then we cannot expect the execution order, it depends on thread scheduler.
XI.Default priority
-
The default priority only for the main Thread is 5.
-
But for all the remaining threads it will be inheriting from parent i.e what ever the priority has by default it will be inheriting to the child.
-
Thread class defines the following 2 methods to get / set priority of the thread.
-
1. Public final int getPriority()
-
2. Public final void setPriority(int i)
Eg. T.setPriority(5);
t.setPriority(10);
t.setPriority(100);//error IllegalArgumentException
class MyThread extends Thread {
public void run(){
for(int i=0; i< 10; i++){
sop(“run method executed”);
}
}
}
Class MyTheadDemo {
Psvm(String args[]){
MyThread t = new MyThread();
t.setPriority(10);----1
t.start();
for(int 1=0; i< 10; i++){
sop(“main thread”);
}
}
}
-
If we are commenting line 1 then both run and main thread will have priority 5 and hence we cannot expect the execution order and o/p of the execution.
-
If we are not commenting the line 1 then main thread has priority 10 and child thread has priority 5 and hence child thread will be executed first and main thread later.
-
Child thread 10 times……
-
Main thread 10 times……
XII.The methods to prevent thread execution
-
We can prevent a thread from its execution by using following methods.
-
Yield()
-
Join()
-
Sleep()
A.Yield()
-
Yield() causes, to pause the current thread and give change to other threads which are waiting threads of same priority.
-
If there are no waiting threads or all other threads are low priority then it will continue its execution once again.
Signature of the yield()
Public static native void yield()
New / Born state
Ready / Runnable state
Running state
Dead state
Mythread t = new Mythread()
Thread.yield()
If run method completed
-
The thread which is yielded, when it will get change of execution is decided by thread scheduler and we cannot expect the exact behavior.
Class MyThread extends Thread {
Public void run(){
For(int i=0 i< 10; i++){
Thread.yield(); --- 1
Sop (“run method executed”);
}
}
}
Class MyThereadDemo {
Psvm(String args[]){
MyThread t = new MyThread();
t.start();
for(int i=0; i< 10 ; i++){
sop (“main method“);
}
}
}
-
If we are commenting line 1 both threads will be executed simultaneously and we cannot expect exact behavior and exact execution order.
-
If we uncomment line 1 there are chances of completing the main thread first and later child thread because of the child thread yield method.
B.Join ()
-
If a thread wants to wait until some other thread to finish his execution then we should go for join().
Eg :
Venue fixing (t1)
Cardprinting (t2) – t1.join()
Carddistribution (t3) – t2.join()
Eg 2 :
-
If Thread t1 executes t2.join() then t1 thread will entered into waiting state until t2 completes. Once t2 thread completes then t1 will continue its execution.
Public void join() throws InterruptedException
Public void join(long ms) throws InterruptedException
Public void join (long ns, int ms) throws InterruptedException
-
Join method is loverloaded an every method throws InterruptedException. Hence whenever we are using join compulsory it should be in try, catch block or by throws otherwise we will get compile time error.
-
Waiting state blocked for join
If run method completed
T2.join() t2.join(1000) t2.join(1000,1000)
New / Born state
Ready / Runnable state
Running state
Dead state
Mythread t = new Mythread()
If run method completed
Class MyThread extends Thread {
Public void run(){
For(int i=0; i<10; i++){
Sop(“run method executed”);
try{
Thread.sleep(2000);
}catch(Exception e){
Sop(“exception”);
}
}
}
Class ThreadJoinDemo {
Psvm (String [] main){
MyThread t = new MyThread();
t.start();
t.join(); --------- 1
for(int i=0; i<10; i++){
sop(“Main thread”)
}
}
}
-
If we are commenting line 1 then both threads will be executed simultaneously and we cannot expect exact order and hence we cannot except exact o/p.
-
If we uncomment line 1 then main thread will wait until child thread to complete. Hence in this case the o/p is expected.
o/pchild thread 10 times
Main thread 10 times
C.Sleep ()
-
If a thread does not want to perform any thing for the particular amount of time (pausing) then we should go for sleep.
Public static void sleep(long ns) throws InterruptedException
Public static void sleep(long ms, int ns) throws InterruptedException
-
When ever we are using sleep () compulsory we should handle Interrupted exception otherwise we will get compile time errors.
Class Test {
Psvm (String args[]){
Sop(“main method called”);
Thread.sleep(2000);
}
}
XIII.Interruption of the Thread
-
A thread can interrupt another sleeping or waiting thread.
-
For this thread class defines interrupt () method.
Public void interrupt()
Class MyThread extends Thread {
Public void run(){
For (int i=0 ; i< 10; i++){
Sop(“child thread”);
try{
sleep(1000);
}catch(IntrruptedException e){
Sop(“I am InterruptedException”);
}
}
}
}
Class MyThreadDemo {
P s v main(String args[]){
MyThead t = new MyThread();
t.start();
t.interrupt();----- 1
sop(“end of the main”);
}
}
-
If we are commenting line 1 then main thread won’t interrupt child thread hence both threads will be executed until completion.
-
If we are not commenting the line 1 then main thread interrupted child thread hence we get out as below
Child thread
I am interrupted exception
End of main
NOTE :
-
We may not see the interrupted impact immediately.
-
When ever we are calling interrupted method if the target thread is not in sleeping or waiting state then there is no impact immediately, Interrupt call will wait until target thread entered into the sleeping or wait state. Once target thread entered into the sleeping or waiting state the interrupt call will impact the target thread.
Comparison table of yield() join() sleep()
property
Yield
Join
Sleep
Purpose
To pause the current executing thread and give chance to the other threads which has same priority
if a thread wants to wait until other threads to complete their task then we should go for join
If a thread does’t want to perform any operation for certain amount to time, then we should go for sleep
Static
Yes
No
Yes
Is it overloaded
No
Yes
Yes
Is it final
No
Yes
No
Is it throws InterruptException
No
Yes
Yes
Is it native method
Yes
No
Sleep(long ms) - native
XIV.Inter thread communication
-
Two threads will communicate with each other by using wait(), notify(), notifyAll() methods. The thread which requires updation is called wait(). The thread which responsible to update is called notify().
-
Wait() notify() notify() methods are available in object class not in Thread calls, because threads are required to call these on any shared object.
-
If a thread wants to call wait() notify() notifyall() methods, compulsory the thread should be owner of the object. i.e the thread has to get lock of the object i.e the thread should be in a synchronized area.
-
Hence we can call wait() notify() notifyAll() methods in synchronized block other wise we will get runtimeexcepton IllegalMonitorstateException.
-
If a thread calls wait method it releases the lock immediately and entered into the wait state. A thread releases the lock of only current object but not all locks after calling notify() or notifyAll() methods, thread releases the lock but may not immediately. Except wait(), notify(), notifyAll() there are no other cases where thread releases the lock.
Public final void wait() throws IE
Public final native void wait(long ms) throws lE
Public final void wait(long ms, int s)throws IE
Public final native void notify()
Public final native void notifyAll()
XV.Producer – consumer problem
-
Consume has to consume items from the queue.
-
If queue is empty he has to call wait() method.
-
Producer has to produce items into the queue.
-
After producing the items, he has to call notify method so that all waiting consumes will get notified.
XVI.Notify() v notifyAll()
-
We can use notify() to notify only one waiting thread but which waiting thread will be notified we cannot expect the exact outcome. All remaining threads has to wait for further notifications.
-
We can use notifyAll() to notify all waiting threads will be notified but thread will be notifying but threads will be executed one by one.
XVII.Synchronization
-
Synchronized is the modifier applicable only for blocks and methods and it cannot be applied to classes and variables.
-
If a method / block is declared as synchronized then at a time only one thread can allowed to execute that method or block on the given object.
-
The main advantage of the synchronized key word is we can resolve data inconsistency problem.
-
The main limitation of the synchronized keyword is it increases the waiting time of the thread and effects performance of the system.
-
Hence if there is no specific requirement it’s never recommended to use synchronized key word.
-
Every object in java has a unique lock synchronization concept internally implemented by using this Lock concept. Whenever we are using synchronized concept this will come into the picture.
-
If a thread wants to execute any synchronized method on the given object, first it has to get the lock of the object. Once it get a lock then it is allowed to execute any synchronized method on that object.
-
Once synchronized method completes then automatically the lock will be released.
-
While a thread executing any synchronized method on the given object the remaining threads are not allowed to synchronized method on the given object simultaneously. But remaining threads are allowed to execute any non synchronized methods simultaneously (lock concept is implemented based on object but not on method).
-
Eg.
Class x {
Sync m1() {}
Sync m2() {}
M3() {}
}
Class Display {
Public void synchronized wish(String name){
For(int i=0; i< 10; i++){
Sop(“good morning”);
Try {
Thread.sleep(3000);
}catch(IE e){
Sop();
}
Sop();
}
}
}
Class MyThread extends Thread {
}