Multi ThreadingAgenda
IntroductionMultitasking: Executing several tasks simultaneously is the concept of multitasking. There are two types of multitasking's.
![]() Process based multitasking:Executing several tasks simultaneously where each task is a separate independent process such type of multitasking is called process based multitasking.Example:
Thread based multitasking:Executing several tasks simultaneously where each task is a separate independent part of the same program, is called Thread based multitasking.And each independent part is called a "Thread".
The ways to define instantiate and start a new Thread:What is singleton? Give example?We can define a Thread in the following 2 ways.
Defining a Thread by extending "Thread class":Example:![]() class ThreadDemo { public static void main(String[] args) { MyThread t=new MyThread();//Instantiation of a Thread t.start();//starting of a Thread for(int i=0;i<5;i++) { System.out.println("main thread"); } } } Case 1: Thread Scheduler:
Case 2: Difference between t.start() and t.run() methods.
Output: child thread child thread child thread child thread child thread child thread child thread child thread child thread child thread main thread main thread main thread main thread main threadEntire output produced by only main Thread. Case 3: importance of Thread class start() method.For every Thread the required mandatory activities like registering the Thread with Thread Scheduler will takes care by Thread class start() method and programmer is responsible just to define the job of the Thread inside run() method.That is start() method acts as best assistant to the programmer. Example: start() { 1. Register Thread with Thread Scheduler 2. All other mandatory low level activities. 3. Invoke or calling run() method. }We can conclude that without executing Thread class start() method there is no chance of starting a new Thread in java. Due to this start() is considered as heart of multithreading. 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.Example: class MyThread extends Thread {} class ThreadDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); } }It is highly recommended to override run() method. Otherwise don't go for multithreading concept. Case 5: Overloding of run() method.We can overload run() method but Thread class start() method always invokes no argument run() method the other overload run() methods we have to call explicitly then only it will be executed just like normal method.Example: class MyThread extends Thread { public void run() { System.out.println("no arg method"); } public void run(int i) { System.out.println("int arg method"); } } class ThreadDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); } } Output: No arg method 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 no new Thread will be started.Example: class MyThread extends Thread { public void start() { System.out.println("start method"); } public void run() { System.out.println("run method"); } } class ThreadDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); System.out.println("main method"); } } Output: start method main methodEntire output produced by only main Thread. Note : It is never recommended to override start() method. Case 7:Example 1:![]() Example 2: ![]() Output: ![]() Case 8: life cycle of the Thread:Diagram:![]()
Case 9:After starting a Thread we are not allowed to restart the same Thread once again otherwise we will get runtime exception saying "IllegalThreadStateException".Example: MyThread t=new MyThread(); t.start();//valid ;;;;;;;; t.start();//we will get R.E saying: IllegalThreadStateException Defining a Thread by implementing Runnable interface:We can define a Thread even by implementing Runnable interface also.Runnable interface present in java.lang.pkg and contains only one method run(). Diagram: ![]() Example: ![]() class ThreadDemo { public static void main(String[] args) { MyRunnable r=new MyRunnable(); Thread t=new Thread(r);//here r is a Target Runnable t.start(); for(int i=0;i<10;i++) { System.out.println("main thread"); } } } Output: main thread main thread main thread main thread main thread main thread main thread main thread main thread main thread child Thread child Thread child Thread child Thread child Thread child Thread child Thread child Thread child Thread child ThreadWe can't expect exact output but there are several possible outputs. Case study:MyRunnable r=new MyRunnable(); Thread t1=new Thread(); Thread t2=new Thread(r); Case 1: t1.start():A new Thread will be created which is responsible for the execution of Thread class run()method.Output: main thread main thread main thread main thread main thread Case 2: t1.run():No new Thread will be created but Thread class run() method will be executed just like a normal method call.Output: main thread main thread main thread main thread main thread Case 3: t2.start():New Thread will be created which is responsible for the execution of MyRunnable run() method.Output: main thread main thread main thread main thread main thread child Thread child Thread child Thread child Thread child Thread Case 4: t2.run():No new Thread will be created and MyRunnable run() method will be executed just like a normal method call.Output: child Thread child Thread child Thread child Thread child Thread main thread main thread main thread main thread main thread Case 5: r.start():We will get compile time error saying start()method is not available in MyRunnable class.Output: Compile time error E:\SCJP>javac ThreadDemo.java ThreadDemo.java:18: cannot find symbol Symbol: method start() Location: class MyRunnable Case 6: r.run():No new Thread will be created and MyRunnable class run() method will be executed just like a normal method call.Output: child Thread child Thread child Thread child Thread child Thread main thread main thread main thread main thread main thread
In which of the above cases a new Thread will be created which is responsible for the execution of MyRunnable run() method ?
In which of the above cases a new Thread will be created ?
In which of the above cases MyRunnable class run() will be executed ?
Best approach to define a Thread:
Thread class constructors:
![]() Diagram: ![]() Output: main method run method Getting and setting name of a Thread:
Example: class MyThread extends Thread {} class ThreadDemo { public static void main(String[] args) { System.out.println(Thread.currentThread().getName());//main MyThread t=new MyThread(); System.out.println(t.getName());//Thread-0 Thread.currentThread().setName("Bhaskar Thread"); System.out.println(Thread.currentThread().getName());//Bhaskar Thread } }Note: We can get current executing Thread object reference by using Thread.currentThread() method. Thread Priorities
Default priority:The default priority only for the main Thread is 5. But for all the remaining Threads the default priority will be inheriting from parent to child. That is whatever the priority parent has by default the same priority will be for the child also.Example 1: class MyThread extends Thread {} class ThreadPriorityDemo { public static void main(String[] args) { System.out.println(Thread.currentThread().getPriority());//5 Thread.currentThread().setPriority(9); MyThread t=new MyThread(); System.out.println(t.getPriority());//9 } } Example 2: class MyThread extends Thread { public void run() { for(int i=0;i<10;i++) { System.out.println("child thread"); } } } class ThreadPriorityDemo { public static void main(String[] args) { MyThread t=new MyThread(); //t.setPriority(10); //----> 1 t.start(); for(int i=0;i<10;i++) { System.out.println("main thread"); } } }
Output: child thread child thread child thread child thread child thread child thread child thread child thread child thread child thread main thread main thread main thread main thread main thread main thread main thread main thread main thread main threadSome operating systems(like windowsXP) may not provide proper support for Thread priorities. We have to install separate bats provided by vendor to provide support for priorities. The Methods to Prevent a Thread from Execution:We can prevent(stop) a Thread execution by using the following methods.
yield():
![]() Example: class MyThread extends Thread { public void run() { for(int i=0;i<5;i++) { Thread.yield(); System.out.println("child thread"); } } } class ThreadYieldDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); for(int i=0;i<5;i++) { System.out.println("main thread"); } } } Output: main thread main thread main thread main thread main thread child thread child thread child thread child thread child threadIn the above program child Thread always calling yield() method and hence main Thread will get the chance more number of times for execution. Hence the chance of completing the main Thread first is high. Note : Some operating systems may not provide proper support for yield() method. Join():If a Thread wants to wait until completing some other Thread then we should go for join() method.Example: If a Thread t1 executes t2.join() then t1 should go for waiting state until completing t2. Diagram: ![]()
![]() Every join() method throws InterruptedException, which is checked exception hence compulsory we should handle either by try catch or by throws keyword. Otherwise we will get compiletime error. Example: class MyThread extends Thread { public void run() { for(int i=0;i<5;i++) { System.out.println("Sita Thread"); try { Thread.sleep(2000); } catch (InterruptedException e){} } } } class ThreadJoinDemo { public static void main(String[] args)throws InterruptedException { MyThread t=new MyThread(); t.start(); //t.join(); //--->1 for(int i=0;i<5;i++) { System.out.println("Rama Thread"); } } }
Waiting of child Thread untill completing main Thread :Example: class MyThread extends Thread { static Thread mt; public void run() { try { mt.join(); } catch (InterruptedException e){} for(int i=0;i<5;i++) { System.out.println("Child Thread"); } } } class ThreadJoinDemo { public static void main(String[] args)throws InterruptedException { MyThread mt=Thread.currentThread(); MyThread t=new MyThread(); t.start(); for(int i=0;i<5;i++) { Thread.sleep(2000); System.out.println("Main Thread"); } } } Output : Main Thread Main Thread Main Thread Main Thread Main Thread Child Thread Child Thread Child Thread Child Thread Child ThreadNote : If main thread calls join() on child thread object and child thread called join() on main thread object then both threads will wait for each other forever and the program will be hanged(like deadlock if a Thread class join() method on the same thread itself then the program will be hanged ). Example : class ThreadDemo { public static void main() throws InterruptedException { Thread.currentThread().join(); --------------- -------- main main } } Sleep() method:If a Thread don't want to perform any operation for a particular amount of time then we should go for sleep() method.
![]() Example: class ThreadJoinDemo { public static void main(String[] args)throws InterruptedException { System.out.println("M"); Thread.sleep(3000); System.out.println("E"); Thread.sleep(3000); System.out.println("G"); Thread.sleep(3000); System.out.println("A"); } } Output: M E G A Interrupting a Thread:How a Thread can interrupt another thread ? If a Thread can interrupt a sleeping or waiting Thread by using interrupt()(break off) method of Thread class. public void interrupt(); Example: class MyThread extends Thread { public void run() { try { for(int i=0;i<5;i++) { System.out.println("i am lazy Thread :"+i); Thread.sleep(2000); } } catch (InterruptedException e) { System.out.println("i got interrupted"); } } } class ThreadInterruptDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); //t.interrupt(); //--->1 System.out.println("end of main thread"); } }
End of main thread I am lazy Thread: 0 I got interruptedNote:
Example: class MyThread extends Thread { public void run() { for(int i=0;i<5;i++) { System.out.println("iam lazy thread"); } System.out.println("I'm entered into sleeping stage"); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("i got interrupted"); } } } class ThreadInterruptDemo1 { public static void main(String[] args) { MyThread t=new MyThread(); t.start(); t.interrupt(); System.out.println("end of main thread"); } }
Compression of yield, join and sleep() method?
Synchronization
Example: class Display { public synchronized void wish(String name) { for(int i=0;i<5;i++) { System.out.print("good morning:"); try { Thread.sleep(1000); } catch (InterruptedException e) {} System.out.println(name); } } } class MyThread extends Thread { Display d; String name; MyThread(Display d,String name) { this.d=d; this.name=name; } public void run() { d.wish(name); } } class SynchronizedDemo { public static void main(String[] args) { Display d1=new Display(); MyThread t1=new MyThread(d1,"dhoni"); MyThread t2=new MyThread(d1,"yuvaraj"); t1.start(); t2.start(); } }If we are not declaring wish() method as synchronized then both Threads will be executed simultaneously and we will get irregular output. Output: good morning:good morning:yuvaraj good morning:dhoni good morning:yuvaraj good morning:dhoni good morning:yuvaraj good morning:dhoni good morning:yuvaraj good morning:dhoni good morning:yuvaraj dhoniIf we declare wish()method as synchronized then the Threads will be executed one by one that is until completing the 1st Thread the 2nd Thread will wait in this case we will get regular output which is nothing but Output: good morning:dhoni good morning:dhoni good morning:dhoni good morning:dhoni good morning:dhoni good morning:yuvaraj good morning:yuvaraj good morning:yuvaraj good morning:yuvaraj good morning:yuvaraj Case study:Case 1:Display d1=new Display(); Display d2=new Display(); MyThread t1=new MyThread(d1,"dhoni"); MyThread t2=new MyThread(d2,"yuvaraj"); t1.start(); t2.start();Diagram: ![]() Even though we declared wish() method as synchronized but we will get irregular output in this case, because both Threads are operating on different objects. Conclusion : If multiple threads are operating on multiple objects then there is no impact of Syncronization. Class level lock:
Synchronized block:
Example 1: To get lock of current object we can declare synchronized block as follows.
Example 2: To get the lock of a particular object 'b' we have to declare a synchronized block as follows.
Example 3: To get class level lock we have to declare synchronized block as follows. Note:As the argument to the synchronized block we can pass either object reference or ".class file" and we can't pass primitive values as argument [because lock concept is dependent only for objects and classes but not for primitives]. Example: Int x=b; Synchronized(x){} Output: Compile time error. Unexpected type. Found: int Required: reference Questions:
Inter Thread communication (wait(),notify(), notifyAll()):
Example 1: class ThreadA { public static void main(String[] args)throws InterruptedException { ThreadB b=new ThreadB(); b.start(); synchronized(b) { System.out.println("main Thread calling wait() method");//step-1 b.wait(); System.out.println("main Thread got notification call");//step-4 System.out.println(b.total); } } } class ThreadB extends Thread { int total=0; public void run() { synchronized(this) { System.out.println("child thread starts calcuation");//step-2 for(int i=0;i<=100;i++) { total=total+i; } System.out.println("child thread giving notification call");//step-3 this.notify(); } } } Output: main Thread calling wait() method child thread starts calculation child thread giving notification call main Thread got notification call 5050Example 2: Producer consumer problem:
![]() Example: ![]() Notify vs notifyAll():
Example: ![]() Which of the folowing statements are True ?
Dead lock:
Example: class A { public synchronized void foo(B b) { System.out.println("Thread1 starts execution of foo() method"); try { Thread.sleep(2000); } catch (InterruptedException e) {} System.out.println("Thread1 trying to call b.last()"); b.last(); } public synchronized void last() { System.out.println("inside A, this is last()method"); } } class B { public synchronized void bar(A a) { System.out.println("Thread2 starts execution of bar() method"); try { Thread.sleep(2000); } catch (InterruptedException e) {} System.out.println("Thread2 trying to call a.last()"); a.last(); } public synchronized void last() { System.out.println("inside B, this is last() method"); } } class DeadLock implements Runnable { A a=new A(); B b=new B(); DeadLock() { Thread t=new Thread(this); t.start(); a.foo(b);//main thread } public void run() { b.bar(a);//child thread } public static void main(String[] args) { new DeadLock();//main thread } } Output: Thread1 starts execution of foo() method Thread2 starts execution of bar() method Thread2 trying to call a.last() Thread1 trying to call b.last() //here cursor always waiting. Note : If we remove atleast one syncronized keywoed then we won't get DeadLOck.Hence syncronized keyword in the only reason for DeadLock due to this while using syncronized keyword we have to handling carefully. Daemon Threads: The Threads which are executing in the background are called daemon Threads. Garbage collector When ever the program runs with low memory the JVM will execute Garbage Collector to provide free memory. So that the main Thread can continue it's execution.
Example: class MyThread extends Thread { } class DaemonThreadDemo { public static void main(String[] args) { System.out.println(Thread.currentThread().isDaemon()); MyThread t=new MyThread(); System.out.println(t.isDaemon()); 1 t.start(); t.setDaemon(true); System.out.println(t.isDaemon()); } } Output: false false RE:IllegalThreadStateException Example: class MyThread extends Thread { public void run() { for(int i=0;i<10;i++) { System.out.println("lazy thread"); try { Thread.sleep(2000); } catch (InterruptedException e) {} } } } class DaemonThreadDemo { public static void main(String[] args) { MyThread t=new MyThread(); t.setDaemon(true); //-->1 t.start(); System.out.println("end of main Thread"); } } Output: End of main Thread
Lazy thread
Deadlock vs Starvation:
How to kill a Thread in the middle of the line?
suspend and resume methods:
RACE condition:Executing multiple Threads simultaneously and causing data inconsistency problems is nothing but Race conditionwe can resolve race condition by using synchronized keyword. ThreadGroup:Based on functionality we can group threads as a single unit which is nothing but ThreadGroup.ThreadGroup provides a convenient way to perform common operations for all threads belongs to a perticular group.
We can create a ThreadGroup by using the following constructors
We can attach a Thread to the ThreadGroup by using the following constructor of Thread class ThreadGroup g=new ThreadGroup("Printing Threads"); MyThread t1=new MyThread(g,"Header Printing"); MyThread t2=new MyThread(g,"Footer Printing"); MyThread t3=new MyThread(g,"Body Printing"); ----------- g.stop(); ThreadLocal(1.2 v):We can use ThreadLocal to define local resources which are required for a perticular Thread like DBConnections, counterVariables etc.,We can use ThreadLocal to define Thread scope like Servlet Scopes(page,request,session,application). GreenThread:Java multiThreading concept is implementing by using the following 2 methods :
GreenThread ModelThe threads which are managed completely by JVM without taking support for underlying OS, such type of threads are called Green Threads.Native OS Model
Life cycle of a Thread:![]() What is the difference between extends Thread and implements Runnable?
If we extend Thread class, there is no scope to extend another class.
Example:
How can you stop a Thread which is running?
Step 1:
Declare a boolean type variable and store false in that variable.
Step 2:
If the variable becomes true return from the run() method.
Step 3:
Whenever to stop the Thread store true into the variable. Questions:
|