Image

Java - Core Java - Multithreading

Multithreading

The Java run-time system depends on threads for many things, and all the class libraries are designed with multithreading in mind. In fact, Java uses threads to enable the entire environment to be asynchronous. A flow of control is known as thread.

If a program contains multiple flows of controls for achieving concurrent execution then that program is known as multi threaded program.

Multitasking

Executing multiple task at a time is called multitasking.

There are two types of multitasking
  • Process based multitasking
  • Thread based multitasking
  • In information technology we can develop two types of applications. They are process based applications and thread based applications.

    A multithreaded program contains two or more parts that can run concurrently. Each parts of such program is called thread.

    Process based multitasking

    Executing multiple task simultaneously is called process based multitasking. It allows computer to run two or more task concurrently but each task is a separate independent process.

    Thread based multitasking

    Executing multiple task concurrently is called In thread based multitasking environment, here each task is a separate independent part of single process and this independent part is called as thread.

    Thread

  • It is an independent sequential flow of execution or path
  • Thread is a stack created in Java stack area
  • It execute method in sequence one after one
  • Multithreading

    It is the process of creating multiple threads in java stack area for executing multiple task concurrently to finish their execution in short time by using processor ideal time effectively.

    Thread life cycle

    1567141552-image.png

    The Newborn state

    When a thread is called, it is in the newborn state, that is, when it has been created and is not yet running. In other words, a start () method has not been invoked on this thread. In this state, system resources are not yet allocated to the thread. When a thread is in the newborn state, calling any method other than start () method causes an IllegalThreadStateException.

    The Runnable state

    A thread in the runnable state is ready for execution but is not being executed currently. Once a thread is in the runnable state, it gets all the resources of the system (as, for example, access to the CPU) and moves on to the running state. All runnable threads are in a queue and wait for CPU access. When the start () method is called on the newborn thread, it will be in the runnable state. It is not in the running state yet because system resources such as the CPU are not available.

    The Running state

    After the runnable state, if the thread gets CPU access, it moves into the running state. Thread will be in the running state unless one of the following things occurs:

  • It dies (that is, the run () method exits).
  • It gets blocked to the input/output for some reason.
  • It calls sleep (), It calls wait (), It calls yield ().
  • It is preempted by a thread of higher priority.
  • Its quantum (time slice) expires.
  • A thread with a higher priority than the running thread can preempt the running thread if any of the following situations arise:

  • If the thread with the higher priority comes out of the sleeping state.
  • The I/O completes for a thread with a higher priority waiting for that I/O.
  • Either notify () or notifyAll () is called on a thread that called wait.
  • When a thread calls the wait () method it goes in the waiting state. To wake up this thread, some other running thread should notify it.

    The dead state

    A thread goes into the dead state in two ways:
  • If its run () method exits.
  • A stop () method is invoked.
  • The run () method exits when it finished execution naturally or throws an uncaught exception. The stop () method kills the thread. A thread in the dead state cannot be executed further.

    The blocked state

    A thread can enter the blocked state when one of the following five conditions occurs: When sleep (), suspend(), wait () is called,

    The thread calls an operation, (For example, during input/output, a thread will not return until the I/O operation completes.),

    The thread is waiting for monitor.

    A thread in the blocked state waits for some action to happen so that it can get ready. That is, if the thread requires some of the I/O operation, it will enter into the blocked state by giving the access to the CPU to another thread. After completion of the I/O operations it will enter into the runnable state.

    The thread can be created by two ways
  • By extending Thread class
  • By implementing Runnable interface
  • Developing custom thread extending from Thread class
    class MyThread extends Thread
    {
        public void run()
        {
            for(int i=0;i<10;i++)
            {
                System.out.println("Child Thread");
            }
        }
    }
    public class ThreadDemo1 {
        public static void main(String[] args) {
            MyThread t=new MyThread();
     
            t.start();
    //        t.run();
            //t.setPriority(10);
            for(int i=0;i<10;i++)
            {
                System.out.println("Main Thread");
            }
        }    
    }

    When we create subclass object, Thread class object is also created by using its no argument constructor. When start() method is called using subclass object custom thread is created in Java stack area, and its execution started by executing run() method from subclass based in processor busy.

    Developing custom thread implementing from Runnable interface
    public class HelloRunnable implements Runnable {
        public void run() {
            System.out.println("Hello from a thread!");
        }
     
        public static void main(String args[]) {
          //  (new Thread(new HelloRunnable())).start();
        Thread t=new Thread(new HelloRunnable());
        t.start();
        }
    }
    

    When we create subclass object Thread class object is not created, because it is not a subclass of Thread. To call start() method we should create Thread class object explicitly by using Runnable parameter constructor, using thisThread class object we should call start() method. After this custom thread is created in Java stack area and its execution is started by executing run() method from Runnable interface subclass based on processor busy.

    Synchronization

    The process of allowing multiple threads to modify an object in a sequence is called synchronization. It is possible by executing that object’s mutator methods logic in sequence from multiple threads.

    Synchronized is a modifier applicable only for methods and blocks but not for classes and variables. If multiple threads are trying to operate simultaneously on the same Java object then there may be a chance of data inconsistency problem. To overcome this problem we should go for synchronized keyword. If a method or block declared as a synchronized then at a time only one thread is allowed to execute that method or block on the given object, so that data inconsistency problem will be resolved. The advantage is that to overcome data inconsistency and disadvantages is that, It increases waiting time of thread.

    Program to check balance
    class Bank
    {
        private double balance;
        public synchronized void withdrawl(int amt)
        {
            System.out.println("The balance before withdrawl"+balance);
            balance=balance-amt;
            System.out.println("The balance after withdrawl"+balance);
        }
    }
    public class SynchronizedDemo {
     
        public static void main(String[] args) {
            Bank b=new Bank();
            b.withdrawl(13000);
        }    
    }