Recent Posts

Friday, 5 August 2016

Threads And Concurrency Tutorial Part 2


2. By Implementing Runnable Interface
      We can define a Thread by implementing runnable interface also. Runnable interface available in java.lang package and contains only one method
public void run();


E.g
class MyRunnable implements Runnable {
   public void run() {
      for (int i = 0; i < 5; i++) {
         System.out.println("Child Thread");
      }
   }
}
 
public class MultiThreadDemo {
   public static void main(String[] args) throws InterruptedException {
      MyRunnable r = new MyRunnable();
      Thread t = new Thread(r);
      t.start();
      for (int i = 0; i < 5; i++) {
         System.out.println("Main Thread");
      }
   }
}

Possible Output
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
E.g
MyRunnable r = new MyRunnable();
Thread t1 = new Thread();
Thread t2 = new Thread(r);
Case 1
t1.start();
     A new thread will be started and executes thread class run method(Which is having 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 and responsible for execution of MyRunnable run method.

Case 4
t2.run();
     No new thread will be created and MyRunnable run method will be executed just like a normal method call.

Case 5
r.run();
     No new thread will be created and MyRunnable run method will be executed just like a normal method call.

Case 6
r.start();
     Compiler Error: MyRunnable doesn’t contain start method

Note
     Among 2- approaches of defining a thread – implements Runnable is always recommended to use in the 1st approach as we are already extending thread class. There is no chance of extending any other class. Hence we are missing the key benefits of oops inheritance(reusability). Hence this approach is not recommended to use.

Hybrid Mechanism To define a thread(not recommended to use)
E.g
class MyThread extends Thread {
   public void run() {
      System.out.println("Child Thread");
   }
}
class HybridThreadDemo {
   public static void main(String arg[]) {
      MyThread t1 = new MyThread();
      Thread t = new Thread(t1);
      t.start();
      System.out.println("Main Thread");
   }
}

Output
Child Thread
Main Thread
Or
Main Thread
Child Thread
Thread class construtors
1. Thread t = new Thread();
2. Thread t = new Thread(Runnable r);
3. Thread t = new Thread(String name);
4. Thread t = new Thread(Runnable r, String name);
5. Thread t = new Thread(ThreadGroup g, String name);
6. Thread t = new Thread(ThreadGroup g, Runnable r);
7. Thread t = new Thread(ThreadGroup g, Runnable r, String name);
8. Thread t = new Thread(ThreadGroup g, Runnable r, String name, long stacksize);
Setting and Getting the name of a Thread
    Every Thread in java has some name it may be provided explicitly by the programmer or automatically generated by JVM. Thread class defines the following methods to set and get the name of a Thread.
1. public final void setName(String name);
2. public final String getName();
E.g
class Test {
   public static void main(String arg[]) {
      System.out.println(Thread.currentThread().getName());
      Thread.currentThread().setName("My Main Thread");
      System.out.println(Thread.currentThread().getName());
   }
}

Output
main
My Main Thread
Thread Priorities
     Every Thread in java having some priority. The range of valid thread priorities is (1-10) (1 is least & 10 is Highest). Thread class defines the following constant for representing some standard priorities.
Thread.MIN_PRIORITY  -> 1
Thread.NORM_PRIORITY -> 5
Thread.MAX_PRIORITY  -> 10
     Thread scheduler use these priorities while allocating C.P.U. The Thread which is having highest priority will get chance first for execution. If two threads having the same priority then which thread will get chance first for execution is decided by Thread Scheduler, which is vendor dependent i.e we can’t expect exactly.

     The default priority for the main thread only the 5, but for all the remaining threads the priority will be inherit from parent i.e what ever the parent has the same priority the child thread also will get.

      Thread class contains the following methods to set and get priorities of thread.
1. public final void setPriority(int priority);
     Where priority should be from 1-10 other wise R.E: IllegalArgumentException.
2. public final int getPriority();
E.g
class MyThread extends Thread {
   public void run() {
      for (int i = 0; i < 5; i++) {
         System.out.println("Child Thread");
      }
   }
}

public class MyThreadPriority {
   public static void main(String arg[]) {
      MyThread t = new MyThread();
      System.out.println(t.getPriority());
      t.setPriority(10);
      t.start();
      for (int i = 0; i < 5; i++) {
         System.out.println("Main Thread");
      }
   }
}
Output
5
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Preventing Thread from execution
     We can prevent a thread from execution by using the following methods.
1. yield()
2. join()
3. sleep()

yield()
     The thread which is called yield() method temporarily pause the execution to give the chance for remaining threads of same priority. If there is no waiting thread or all waiting threads having low priority. Then the same thread will get the chance immediately for the execution.
E.g
class MyThread extends Thread {
   public void run() {
      for (int i = 0; i < 5; i++) {
         System.out.println("Child Thread");
         Thread.yield();
      }
   }
}

public class MyThreadYield {
   public static void main(String arg[]) {
      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 Thread
     In this case main thread will get chance more no of times for execution. Because child thread intentionally calling “yield()” method. As the yield method is native method some Operating system may not provide the support for this.

join()
     If a thread wants to wait until some other thread completion then we should go for join method.
E.g
     If a thread t1 executes t2.join(), then t1 will be entered into waiting state until t2 completion.
public final void join() throws InterruptedException
public final void join(long ms) throws InterruptedException
public final void join(long ms, int ns) throws InterruptedException
E.g
class MyThread extends Thread {
   public void run() {
      for (int i = 0; i < 5; i++) {
         System.out.println("Child Thread");
         try {
            Thread.sleep(1000);
         } catch(InterruptedException ie) { }
      }
   }
}

public class MyThreadJoin {
   public static void main(String arg[]) throws InterruptedException {
      MyThread t = new MyThread();
      t.start();
      t.join();
      for (int i = 0; i < 5; i++) {
         System.out.println("Main Thread");
      }
   }
}
Output
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
* If we are commenting t.join() then both Threads will be executed simultaneously and we can't expect exact execution order.

* If we are not commenting t.join() then main Thread will wait until completing child Thread in this the output is Child Thread 5 times followed by Main Thread 5 times.
Waiting of child Thread untill completing main Thread
E.g
class MyThread extends Thread {
   static Thread mt;
   public void run() {
      try {
            mt.join();
         } catch(InterruptedException ie) { }
      for (int i = 0; i < 5; i++) {
         System.out.println("Child Thread");
      }
   }
}

public class MyThreadJoin {
   public static void main(String arg[]) throws InterruptedException {
      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 Thread
Note
     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 ).

sleep() method
      If a method has to wait some predefined amount of time with out execution then we should go for sleep() method.
public static native void sleep(long ms) throws InterruptedException
public static void sleep(long ms,int ns)throws InterruptedException
E.g
class MyThread extends Thread {
   public void run() {
      try {
         for (int i = 0; i < 5; i++) {
            System.out.println("This is Lazy Method");
            Thread.sleep(1000);
         }
      } catch (InterruptedException e) {
         System.out.println(e);
      }
   }
}

public class MyThreadSleep {
   public static void main(String arg[]) throws InterruptedException {
      MyThread t = new MyThread();
      t.start();
      System.out.println("Main Thread");
   }
}
Output
Main Thread
This is Lazy Method
This is Lazy Method
This is Lazy Method
This is Lazy Method
This is Lazy Method

Next Tutorial  Threads and Concurrency Tutorial Part 3

Previous Tutorial  Threads And Concurrency Tutorial Part 1

1 comment: