Multi-threading

Multithreading is the way to achieve multitasking except the multithreading multitasking is also achieved by multiprocessing.
Loading of the multiple task in the memory at the same time for parallel processing is known as the multitasking.
Actually the multiple task share the time slice of the resources for their execution.

Difference b/w Multithreading & Multiprocessing
Multiprocessing
Multithreading
1- A process represents to a complete application. 1- A thread represents to the part of the process.
2- A process always have their separate work space in the memory. 2- Thread share the memory of the process.
3- Process can never share the data. 3- Threads can share the data.
4- creation of a new process is always heavy weighted. 4- creation of the new thread is the light weighted.
5- switching b/w the processes is the heavy weighted. 5- switching b/w threads is the light weighted.
6- Their can be the limited no. Of process in any OS. 6- Their can be unlimited threads in any OS.


All the java applications are the multithreaded applications because in each java application internally the multiple threads works such as garbage collector, class loader, main thread.
                 main thread is responsible for execution of the developer's code started from main()

Note:- programetically we can also create a new threads for parallel execution of different parts of application.

java.lang.Thread class:-An instance of Thread class represents to a thread in the application. This class provides  methods to manage the thread in their life cycle.
                      In the following states a thread can exist:-

                                                               Thread Life Cycle

-new state of Thread means a thread object is created but not eligible for the execution.
-Ready state means, a thread is ready for execution.
                    In the multithreading existence of multiple threads, in this state means the parallel processing of the threads.
                    Any thread can only be moved this state after the invocation of start().
                    with any one thread object only one time.
-Running state means currently the thread is in the execution.
-terminating state means the code of the thread is completed.
-waiting/blocking state, in this state a thread is still alive but their execution is blocked due to any reason.

Methods of Thread class:-

(1) public void setName(String name)
                     -this method is used to set the name of the thread.
(2) public String getName()
                     -this method is used to get the name of the thread. By default the thread names will be as follows-
                Thread-0
                Thread-1..............so on.
(3) public void setPriority(int priority)
                     -this method is used to set the priority of the thread for the execution.
(4) public int getPriority()
                     -this method returns the current priority of the thread.
Note:- A priority of any thread can be with in the range of 1 to 10.
           1 means lowest priority.
           10 means highest priority.
Note:- Thread class also provides static constants for the priority.
            Thread.MIN_PRIORITY          ->1
            Thread.MAX_PRIORITY        ->10
            Thread.NORM_PRIORITY     ->5  (default)
(5) public boolean isAlive()
                     -This method returns true if the thread is still not moving in the terminating state.
(6) public static void sleep(long miliseconds) throws InterruptedException
                    -this method is used to move the thread in waiting state upto the specified miliseconds. If any other thread will interrupt then this thread will throws a InterruptedException and returned back into the ready state.
(7) public void join() throws InterruptedException
                    -this method is used to join one thread with the other thread.
(8) public void start()
                    -this method is used to start the thread.
(9) public static Thread currentThread()
                    -this method will return the reference ID of current thread.
Note:- whenever any thread gets started internally multiple run time resources will be created for that thread such as stack, program counter etc. currentThread means the owner thread of the stack in which this method is invoking.

Execution of Main Thread:-

2. Thread object is created.
3. new Stack is created.
4. Association of the stack with the thread.
5. main() started and loaded into the stack.
6.1 Ref.ID of current thread object obtained.
6.2 Ref.ID copied into main().

class ThreadTest
{
     public static void main(String[] args)
    {
           System.out.println("main thread started.");
           Thread th=Thread.currentThread();
           System.out.println("thread name:"+th.getName());
           System.out.println("thread priority:"+th.getPriority());
           System.out.println("main thread is going to sleep for 5 sec....");
           try
           {
                 Thread.sleep(5000);
           }
           catch(Exception e)
           {
           }
           System.out.println("changing the name & priority");
           th.setName("my main");
           th.setPriority(Thread.MAX_PRIORITY);
           System.out.println("new name:"+th.getName());
           System.out.println("new Priority:"+th.getPriority());
           System.out.println("is alive:"+th.isAlive());
           System.out.println("details of thread [thread name:priority:group]"+th);
    }
}

Note:- The class contains the logic that execute under a Thread is called Runnable class.

Creating a new Thread:- In order to create new thread two things have to be prepared:-
                    (1) Runnable class
                    (2) Thread Object
A Runnable class will be the user defined class that contains the code that will be executed under the thread.
           In order to create a Runnable class we have to implements the java.lang.Runnable interface.
Methods of Runnable:-

public void run()
          -it will always be the first method to be loaded in the stack of the new thread. Thread object can be created with the help of one of the following constructor of Thread-
public Thread()
public Thread(String name)
public Thread(Runnable r)
public Thread(Runnable r,String name)

Steps to create new Thread:-
(1) create Runnable class
(2) create the object of Runnable class.
(3) create the object of java.lang.Thread class and associate the Runnable object with the Thread object.
 start the thread by using the start() of Thread.
Note:- start() of Thread class first of all always creates a new stack then invokes the run() of the Runnable class into the new stack and then invoke the new thread into the ready state from the new state.

class MyRunnable implements Runnable
{
    public void run()
    {
          Thread th=Thread.currentThread();
          String name=th.getName();
          System.out.println(name+" Thread started.");
          for(int i=0;i<=10;i++)
          {
                 System.out.println("hello"+i);
          }
    }
}

class ThreadTest
{
      public static void main(String[] args)
      {
          System.out.println("main method started.");
          Thread mainTh=Thread.currentThread();
          MyRunnable r=new MyRunnable();
          Thread th=new Thread();
          th.start();
          for(int i=0;i<=10;i++)
          {
              System.out.println("main:"+i);
          }
          System.out.println("main is about to terminate.");
      }
}

Note:- Their can be multiple Threads in ready state but only one thread can be in running state.
Note:- A Thread class is also the Runnable class that means it also implements to the java.lang.Runnable interface.

 that's meaning,
                        class Thread extends Object implements Runnable
                        {
                        }

Creating the MyThread class by extends Thread class:-

class MyThread extends Thread
{
      MyThread()
      {
          super();
      }
      public void run()
      {
           String name=getName();
           System.out.println(name+" Thread started.");
           for(int i=0;i<=10;i++)
           {
                System.out.println("hello "+i);
           }
           System.out.println("Thread is about to terminate.");
      }
}
class ThreadTest
{
     public static void main(String []args)
     {
           System.out.println("main thread started.");
           Thread mainTh=Thread.currentThread();
           MyThread th=new MyThread();
           th.start();
           for(int i=0;i<=10;i++)
           {
               System.out.println("main:"+i);
           }
           System.out.println("main is about to terminate.");
     }
}

Thread Interruption:-
                      -whenever any thread is in waiting state their are two reasons to return back from the waiting state-
                  (1) when the purpose gets full filled.
                  (2) when other thread interrupting.
with the following reasons any thread can be moved in the waiting state-
                  (1) By invoking the sleep()
                  (2) By invoking the join()
                  (3) In case of thread synchronization.
                  (4) By invoking the wait()
interrupt() is used to interrupt in any Thread that is currently in the waiting state. One running thread can only interrupt to the other waiting thread.
Note:- as any thread gets interrupted by the other thread it immediatly generates the interrupted Exception.

import java.util.Scanner;
class SumThread extends Thread
{
    String name=getName();
    System.out.println(name+" thread started.");
    System.out.println(name+" thread is waiting for 10 sec....");
    public void run()
    {
          try
          {
               Thread.sleep(10000);
          }
          catch(InterruptedException e)
          {   e.printStackTrace();
          }
          int sum=0;
          sum=sum+InterruptTest.x;
          sum=sum+InterruptedTest.y;
          System.out.println("sum:"+sum);
    }
}
class InterruptTest
{
     static int x,y;
     public static void main(String[] args)
     {
           SumThread th=new SumThread();
           th.setName("sum calc");
           th.start();
           Scanner sc=new Scanner(System.in);
           System.out.println("enter two no:");
           x=sc.nextInt();
           y=sc.nextInt();
           th.interrupt():
           System.out.println("main is going to terminate.");
     }
}

Note:- when all the methods from stack of thread completed successfully then the Thread immediatly moved in the terminating state.

Thread joinning:-
                 -with the join() any thread can join the other thread. The currentThread will be joinning Thread that will be moved in the waiting state.
                 The invoker thread object will be the joint thread.
*creating a user defined thread that will be accept the 10 values from the end user. main thread will join to that user thread and after termination of user thread the main thread will calculate the sum of all values....
import java.util.Scanner;
class InputThread extends Thread
{
      private int[] data=new int[10];
      InputThread(String name)
      {
           super(name);
           this.start();
           public void run()
           {
                 Scanner sc=new Scanner(System.in);
                 System.out.println("enter the values:");
                 for(int i=0;i<10;i++)
                 {
                      data[i]=sc.nextInt();
                 }
           }
           int[] getDat()
           {
                    return (data);
           }
      }
}

class JointTest
{
      public static void main(String[] args)
      {
           InputThread ith=new InputThread("Reader");
           System.out.println("main is going to join the input thread.");
           try
           {
                  ith.join();
           }
           catch(Exception e)
           { e.printStackTrace();
           }
           int sum=0;
           int data[]=ith.getData();
           for(int i=0;i<data.length;i++)
           {
                 sum=sum+data[i];
           }
           System.out.println("sum of values:"+sum);
      }
}

Interrupting the joinning thread:-

class InterruptThread extends Thread
{
       Thread mainTh;
       InterruptThread(Thread th)
       {
             mainTh=th;
             start();
       }
       public void run()
       {
            System.out.println("interrupt thread is going to sleep....");
            try
            {
                   Thread.sleep(10000);
            }
            catch(Exception e)
            {
                   e.printStackTrace();
            }
       }
}

Changes in joinTest:-
 
InputThread ith=new InputThread("Reader");
System.out.pirntln("------------------------");
Thread mainTh=Thread.currentThread();
InterruptedThread itr=new InterruptedThread(mainTh);
try
{
------------------
}
//remainning code remains same.............

Note:- JVM always terminates the program when all the running threads gets terminated.

Daemon Thread:-
                     -These are the secondary Threads that can never be executed isolatedly that means when all the non-daemon threads gets completed immediatly JVM will terminate the program.
                      By default each and every Thread is the non-daemon thread. setDaemon() of Thread class is used to make a Thread as the daemon thread.
public void setDaemon(boolean b)

Note:- any thread can be set as the daemon thread before their starting.

InputThread(String name)
{
         super(name);
         setDaemon(true);
         this.start();
}

Thread Synchronization:-
                     -it is the way through which the anyone object can be accessed by only one thread at a time. 'synchronized' keyword is used to perform the Thread synchronization.
                     use of the synchronized keyword can be as follows-
(1) To make any method synchronized.
(2) To make the synchronized block.
if their are some synchronized methods and blocks in any class then each and every object of that class will have a single lock to provide the accessibility to the threads.
     if any thread invokes the any synchronized methods or block with any object then that object immediatly provides the lock to that thread. and if another thread wants to invoke any synchronized method or block then due to unavailability of the lock that thread have to be moved in the waiting state and wait for the completion of the synchronized method or block invoke by the 1st thread.

class Resource
{
     int data[]={1,2,3,4,5,6,7,8,9,10};
     synchronized void display()
     {
           Thread th=Thread.currentThread();
           String name=th.getName();
           System.out.println("display() invoked by "+name"+" thread.");
           for(int i=0;i<n;i++)
           {
                  System.out.println(name+":"+data[i]);
           }
     }
     synchronized void update()
     {
            Thread th=Thread.currentThread();
            String name=th.getName();
            System.out.println("update() is invoked by "+name+" thread.");
            for(int i=9;i>=0;i--)
            {
                  data[i]+=10;
                  System.out.println((i+1)+" value updated "+data[i]);
            }
     }
}

class MyThread extends Thread
{
      Resource r;
      MyThread(Resource r,String name)
      {
             super(name);
             this.r=r;
             start();
      }
      public void run()
      {
            String name=getName();
            if(name.equals("first"))
                       r.display();
            if(name.equals("second"))
                       r.update();
      }
}

class SynchronizationTest
{
     public static void main(String[] args)
     {
          Resource r=new Resource();
          MyThread th1=new MyThread(r,"first");
          MyThread th2=new MyThread(r,"second");
     }
}

sychronized block:-
                  like the non static method the synchronized block also will be invoked by the ref. of object.
syntax:-
               synchronized(ref_id of object)
               {
                      statements............
               }
Any thread can be entered in the synchronized block when the lock of the argumented object is available.
Benifits of synchronized block:-
   (1) To access any non synchronized method in the synchronized manner.
   (2) To make any method partially synchronized.

changes in last program:-

public void run()
{
      String name=getName();
      synchronized(r)
      {
           if(name.equals("first"))
                    r.display();
           if(name.equals("second"))
                    r.update();
      }
}
Note:- remove the synchronized keyword from the display() and update().

Limitation of synchronized keyword:-
                         -it provides a unordered mutual exclusivity b/w the thread to access the objects. Thats means if one thread start the execution of synchronized method then their is no certain time for the completion of method, upto that time the other thread have to wait.

Inter Thread Communication:-
                        -In case of inter thread communication the threads are capable to access the synchronized objects in the mutually exclusive manner in the ordered way. That means any thread can release the lock during the execution of the synchronized method or block and moved into the waiting state.
   
java.lang.Object class:-   
                       -This class provides the following methods for inter thread communication-
(1) wait()           (2) notify                (3) notifyAll()

(1) wait() - always be invoked from synchronized method or block. It immediatly release the lock of the object and move the thread into the waiting state for the waiting of notification.
(2) notify() - will notify the thread that is currently in the waiting state by invoking the wait() with the same object.
(3) notifyAll() - this method will notify all the threads that are currently in the waiting state.

i will explain the implementation of the above methods in the following video-
                  https://www.youtube.com/watch?v=m1CNpRHzbaw&t=304s
Each and every object has the monitor in which it maintains the references of the threads that are currently required the lock of object. It means all the threads in their stack currently any synchronized method or block currently loaded.
            In the monitor of the object their are the 3 sections where the threads are managed-
(1) Ready
(2) Running
(3) Waiting
 
            whenever any thread is created or shift from waiting state it goes to the ready state first to be executed that means if any thread is in the waiting state by calling the wait() then after any thread other thread will notify this thread by calling notify() then the waiting  thread will first goes to the ready state then it will goes to the Running state.
            and whenever any thread is in waiting state and it invokes the wait() it will goes to the waiting state and it will release the object's lock.

notifyAll():-
                implementation of this method is shown in following video-
https://www.youtube.com/watch?v=w7HgNAmZu38

Comments

Popular posts from this blog

Input/Output Stream in java

Reflection in java

define System.out.println()?