Monday, 30 January 2017

Multi threading

Multi Threading
Multithreading is a programming concept where a program is divided into more than one sub programs called processes, which can be executed in parallel at the same time. Multi tasking feature of an operating system where more than one tasks can be executed at the same time is actually multithreading.
A thread has a single flow of control: Thread has a beginning, body (set of instructions to be executed), and an end. The instructions in the body of the thread are executed sequentially. All main programs we have seen in earlier examples can be called single thread. Java supports multithreading, each thread is a small program which has its own flow of control and runs in parallel of other threads (programs). Main method of java program is actually main thread and it starts other threads. All these threads shares computer resources (CPU RAM etc) jointly. These threads of an main application are also called as lightweight threads or lightweight processes. Multithreading is a powerful concept of the java which allow programmers to do multiple things together. Long programs can be broken into threads and executed in parallel.

Creating Threads
Thread contains run method which is heart of the thread. Run method makes up entire body of the thread.
Example:
public void run()
{
------- // Body of thread          
}
A thread can be created by two methods.
1.      By creating a thread class: Define a class that extends thread class, override run() method  of thread class in new created class and add code in run() method required by the thread.
2.      By converting a class to a thread: Define a class that implements Runnable interface. Runnable interface has only one method run().

Extending Thread class
We can make our thread class by extending the class java.lang.Thread. To create and execute a thread using class Thread we will need to do following:
1.      Declare a class that extends Thread class.
2.       Implement run() method which contains code of thread.
3.      Create object of thread and call start() method.
Example:
There are three classes in this example MyClassOne, MyClassTwo, MyClassThree extends Thread class.  In all the three classes method run() has implemented which displays a message. In main() method object of all the three classes has created objectOne, objectTwo, objectThree. To start threads start function is called objectOne.start(),        objectTwo.start(), objectThree.start().

class MyClassOne extends Thread
{
       public void run()
       {
              System.out.println("My Class One");
       }
}

class MyClassTwo extends Thread
{
       public void run()
       {
              System.out.println("My Class Two");
       }
}

class MyClassThree extends Thread
{
       public void run()
       {
              System.out.println("My Class Three");
       }
}

public class ThreadExample
{
       public static void main(String arg[]){
             
      
              MyClassOne objectOne = new MyClassOne();
              MyClassTwo objectTwo = new MyClassTwo();
              MyClassThree objectThree = new MyClassThree();
             
              objectOne.start();
              objectTwo.start();
              objectThree.start();
      
       }
}
The output of this program is:
My Class Two
My Class One
My Class Three
Note that we called start() function of class one first then of class two and finally class three but if we see result the class two thread was executed first then first then third. Means all three threads executed independently so they displayed result when they executed not in sequence they called.
Stopping a Thread
Some time situation occurs when we want to stop a thread from further execution, we stop a thread from execution by calling a method stop().
Example:
objectOne.stop();
This statement will stop the execution of thread permanently. It will force thread to move to dead state. Thread also move to the dead state when complete body is executed and it reaches to the end.   
Blocking or Pausing a Thread
Thread can be temporarily blocked (paused) from execution when needed.  Following three methods can be used to block (pause) a thread from execution.
1.      sleep(): Blocks execution of a thread for specified time.
2.      suspend(): Blocks thread from execution until further order. A method resume() is used to restart execution of  a suspended thread.
3.      wait(): Block Blocks execution of a thread until certain condition occurs. A method notify() is called to restart for a thread in wait state.
 These methods can be used to force a thread to go into blocked state. Any of these methods can be called to block a thread from execution as per requirement.

Life Cycle of a Thread
Life cycle of a thread contains following states:
1.      Newborn State
2.      Runnable State
3.      Running State
4.      Blocked (Paused) State
5.      Dead State

Newborn State
Creation of an object of a thread is called newborn thread. In this state thread is created but not started, we can perform two operations start() and stop() on the thread in newborn state. The method start() schedule a thread for running and stop() kills the thread (force it to go into dead state). 
Runnable State
Thread which is ready for execution and waiting for availability of the processor is called runnable state of the thread. In this state thread is in the queue of the threads waiting for processor. When we want a thread to release its control and shift control to equal prority thread whose turn has not yet come we use yield() method.
Running State
The thread which is being executed (using CPU) currently is called in running state. A thread runs until it completes execution of all the statements in the body of thread or it is interrupted by the high priority threads. A thread can be interrupted by using following methods sleep(), suspend() or wait().
Blocked State
A thread which is prevented from entering into runnable state and subsequently into running state is called in blocked state.  This happens when thread is suspended, waiting or sleeping due to some reason. Blocked thread is not dead, it can be considered as “not runnable”.
Dead State
Life of a running threads ends when run() method of the thread completes its execution. We can also use stop() method to force a thread to go into dead state. A thread can be killed when it is in newborn state, blocked state or running state.   
Example:
class MyClassOne extends Thread
{
       public void run()
       {
                          
              for(int i=0; i<=5; i++)
              {
                     if(i==2) yield();
                     System.out.println("Counter of Class one: =" + i);
                    
              }
             
              System.out.println("Exit from My Class One !");
       }
}

class MyClassTwo extends Thread
{
       public void run()
       {
             
              for(int i=0; i<=5; i++)
              {
                     System.out.println("Counter of Class Two: =" + i);
                     if(i==3) stop();
              }
              System.out.println("Exit from My Class Two !");
       }
}

class MyClassThree extends Thread
{
       public void run()
       {
             
              for(int i=0; i<=5; i++)
              {
                     System.out.println("Counter of Class Three: =" + i);
                     if(i==2)
                           try {
                                  sleep(1000);
                           } catch (InterruptedException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                           }
              }
              System.out.println("Exit from My Class Three !");
       }
}

public class ThreadExample
{
      
       public static void main(String arg[]){
             
      
              MyClassOne objectOne = new MyClassOne();
              MyClassTwo objectTwo = new MyClassTwo();
              MyClassThree objectThree = new MyClassThree();
             
              System.out.println("Start thread one");
              objectOne.start();
              System.out.println("Start thread two");
              objectTwo.start();
              System.out.println("Start thread three");
              objectThree.start();
             
              System.out.println("Main thread END");
             
       }
}
Output of this program is:
Start thread one
Start thread two
Start thread three
Main thread END
Counter of Class Two: =0
Counter of Class Two: =1
Counter of Class Two: =2
Counter of Class Two: =3
Counter of Class one: =0
Counter of Class one: =1
Counter of Class Three: =0
Counter of Class Three: =1
Counter of Class Three: =2
Counter of Class one: =2
Counter of Class one: =3
Counter of Class one: =4
Counter of Class one: =5
Exit from My Class One !
Counter of Class Three: =3
Counter of Class Three: =4
Counter of Class Three: =5
Exit from My Class Three !

Every time you execute this program it will give slightly different sequence of output. But the effect of methods yield(), stop() and sleep() will be same. In first thread we have used yield() method on condition if(i==2) yield().  So when value of I becomes 2, the control is shifted to next thread. We have used method stop() in second thread on condition if(i==3) stop() so when value of I reaches 3, execution of this thread stopped and no further statement in this thread is executed. Similarly we have used sleep() in thread three if(i==2)… sleep(1000). When value of i becomes 2 then execution of thread blocked for 1000 milliseconds. We will learn exception handling (try… catch) in next chapter.


Priority of Threads
Each thread in java has priority, on the basis of that threads are executed. Threads we created in previous example have same priority. Equal priority threads are executed on first come first serve basis. Java allows us to set the priority of threads using setPriority() method.  The Thread class has some predefined priorities as given below.
MIN_PRIORITY = 1
NORM_PRIORITY = 5
MAX_PRIORITY = 10
Example: MyThread.setPriority(integer)
Parameter passed to the method setPriority() is an integer number between 1 to 10. Execution of threads will be on the basis of their priority. If there are many threads in the queue for execution then highest priority thread will be executed first and lowest priority thread will be executed in the last. If a new thread with higher priority comes in and a thread of lower priority is already executing then execution of already executing thread will be blocked and execution of new higher priority thread will start.
Example:
class MyClassOne extends Thread
{
       public void run()
       {
              System.out.println("Beginning of thread My Class One !");           
              for(int i=0; i<=5; i++)
              {
                     System.out.println("Counter of Class one: =" + i);
              }
             
              System.out.println("Exit from My Class One !");
       }
}

class MyClassTwo extends Thread
{
       public void run()
       {

              System.out.println("Beginning of thread MyClassTwo !");      
              for(int i=0; i<=5; i++)
              {
                     System.out.println("Counter of Class Two: =" + i);
              }
              System.out.println("Exit from My Class Two !");
       }
}

class MyClassThree extends Thread
{
       public void run()
       {
              System.out.println("Beginning of thread MyClassThree !");
              for(int i=0; i<=5; i++)
              {
                     System.out.println("Counter of Class Three: =" + i);
              }
              System.out.println("Exit from My Class Three !");
       }
}

public class ThreadExample
{
      
       public static void main(String arg[]){
                    
              MyClassOne objectOne = new MyClassOne();
              MyClassTwo objectTwo = new MyClassTwo();
              MyClassThree objectThree = new MyClassThree();
             
              objectThree.setPriority(Thread.MAX_PRIORITY);
              objectTwo.setPriority(Thread.NORM_PRIORITY);
              objectOne.setPriority(Thread.MIN_PRIORITY);
             
              System.out.println("Start thread one");
              objectOne.start();
              System.out.println("Start thread two");
              objectTwo.start();
              System.out.println("Start thread three");
              objectThree.start();
             
              System.out.println("Main thread END");
             
       }
}
The output of this program is:
Start thread one
Start thread two
Start thread three
Main thread END
Beginning of thread MyClassTwo !
Counter of Class Two: =0
Counter of Class Two: =1
Counter of Class Two: =2
Counter of Class Two: =3
Counter of Class Two: =4
Counter of Class Two: =5
Exit from My Class Two !
Beginning of thread MyClassThree !
Counter of Class Three: =0
Counter of Class Three: =1
Counter of Class Three: =2
Counter of Class Three: =3
Counter of Class Three: =4
Counter of Class Three: =5
Exit from My Class Three !
Beginning of thread My Class One !
Counter of Class one: =0
Counter of Class one: =1
Counter of Class one: =2
Counter of Class one: =3
Counter of Class one: =4
Counter of Class one: =5
Exit from My Class One !
In the starting of this program thread two started executing. But as thread started it started executing even thread one was created first.
Implementing Runnable Interface
We have created thread using Thread class in previous examples which is one method of creating threads. Another method of creating a thread is by Implementing Runnables Interface. Steps to create thread using Runnable:
1.      Declare a class by implementing Runnable Interface.
2.      Implement run() method same as we have done using Thread class.
3.      Create a thread by define an object of the class we have created.
4.      Call start() method to run the thread.
Example:
class MyClassOne implements Runnable     // Step 1
{
       public void run()                               // Step 2
       {
              System.out.println("Beginning of thread My Class One !");           
              for(int i=0; i<=3; i++)
              {
                     System.out.println("Counter of Class one: =" + i);
              }
             
              System.out.println("Exit from My Class One !");
       }
}

class MyClassTwo implements Runnable     // Step 1
{
       public void run()                               // Step2
       {

              System.out.println("Beginning of thread MyClassTwo !");      
              for(int i=0; i<=3; i++)
              {
                     System.out.println("Counter of Class Two: =" + i);
              }
              System.out.println("Exit from My Class Two !");
       }
}

public class ThreadExample
{
      
       public static void main(String arg[]){
             
      
              MyClassOne runableObjectOne = new MyClassOne();
              MyClassTwo runableObjectTwo = new MyClassTwo();
             
              Thread threadOne = new Thread(runableObjectOne); // Step 3
              Thread threadTwo = new Thread(runableObjectTwo); // Step 3
             
              System.out.println("Start thread one");
              threadOne.start();
              System.out.println("Start thread two");
              threadTwo.start();
             
             
             
       }
}
The output of the program is:
Start thread one
Start thread two
Beginning of thread My Class One !
Counter of Class one: =0
Counter of Class one: =1
Counter of Class one: =2
Counter of Class one: =3
Exit from My Class One !
Beginning of thread MyClassTwo !
Counter of Class Two: =0
Counter of Class Two: =1
Counter of Class Two: =2
Counter of Class Two: =3
Exit from My Class Two !











No comments: