Tuesday, November 19, 2013

Multi-threading

Process :-  A program in execution is called a process e.g running Microsoft word. It is heavyweight component. Two processes can never share same address space. A process has at least one thread which is main, excluding the system threads that help in memory management and signal handling.

Note : IPC (Inter process communication) resources like sockets and pipes are used to communicate between two different processes.

Thread :- A thread is a part of execution with in a process.e.g spell checker in above process. It is  a lightweight component. Two threads of a process can share the same address space.

Note: Programming constructs like wait, notify and notify all used for communication between threads

Life Cycle of thread :-
  1. New (Born). A thread is in new state when its instance is created.
  2. Runnable (Starts) A thread is in runnable state if its starts method is invoked.
  3. Running (Runs): A thread is in running state if thread scheduler has selected it.
  4. Non Runnable:- A thread is in non running state if it alive but is not eligible to run.
  5. Terminated Dies:- A thread is in dead state if its run method exits.
Note :-
  1. There are several ways to enter in Runnable state e.g. on invoking of start() method, after either running, waiting, sleeping or coming back from blocked state etc, but there is only one way to enter in Running state: the scheduler select a thread from runnable pool. 
  2. A running thread can enter to any non-runnable state directly but a non-runnable thread can not enter to running state directly. It has to first enter runnable state.
Non Runnable States:-
  1. Sleeping 
  2. Waiting
  3. Blocked on IO
  4. Blocked on Joint Completion
  5. Blocked on lock acquisition
Thread Priorities:-
Each JAVA thread is given a priority that helps the operating system to determine what thread is needed to be executed and at what priority
  1. MIN_PRIORITY (1)
  2. MAX_PRIORITY (10)
  3. NORM_PRIORITY (5)
Thread Creation:-
  • Extending Thread Class
  • Implementing Runnable Interface(provides multiple inheritance)
Synchronization:- It is the capability of controlling access to shared resources by multiple threads.  
Difference between Thread.start() and Thread.run():-
  1. Thread.start() creates a new thread while Thread.run() runs on the same thread.
  2. start() can not be called twice on the object  as it will throw illegal state exception.
Context Switching
Context Switching is the process of storing and restoring of CPU state so that Thread execution can be resumed from the same point at a later point of time

Thread.join()
This method is used to pause the current thread execution until unless the specified thread is dead. There are three overloaded join functions.
  1. Thread.join():- This method puts the current thread on wait until the thread on which it’s called is dead. If the thread is interrupted, it throws InterruptedException.
  2. Thread.join(long millis):- This method is used to wait for the thread on which it’s called to be dead or wait for specified milliseconds.
  3. Thread.join(long millis, int nanos):- This method is used to wait for thread to die for given milliseconds plus nanoseconds. 
package com.arsoft.tutorials.multithreading;
import java.util.Vector;
public class ThreadTestWithJoin {
    private Vector<String> threadsName = new Vector<String>();
     private void startThreads(int nfOfThreads) {
         Thread[] threads = new Thread[nfOfThreads];
         for (int i = 0; i < threads.length; i++) {
             threads[i] = new MyThread();
             threads[i].start();
         }
         for (int i = 0; i < threads.length; i++) {
             try {
                 threads[i].join();//This means that means that the parent thread is waiting until the thread who called join that is thread[i] ends.
             } catch (InterruptedException e) {
               
             }
         }
     }
     public static void main(String[] args) {
         ThreadTestWithJoin test = new ThreadTestWithJoin();
         test.startThreads(20);
         System.out.println("At the end of main the thread which have executed are \n"+test.threadsName);
         System.out.println("Total threads executed are "+test.threadsName.size());
     }
      class MyThread extends Thread {
         public void run() {
             threadsName.add(getName());
         }
     }
}
Wait, notify and notifyAll methods are in Object class not in thread?

It was a design decision.

Java’s concurrency model needs "locks" and it was decided that each object was to be associated with a lock.

The wait, notify and notifyAll methods are not associated with a thread but with a lock, so the decision of coupling locks and objects meant that each
object should have wait,notify and notifyAll methods that operate on that object’s lock.

Explanation and Example:-

A gas station has a single toilet, the key for which is kept at the service desk. The toilet is a shared resource for passing motorists.
To use this shared resource the prospective user must acquire a key to the lock on the toilet. The user goes to the service desk and acquires the key, opens the door, locks it from the inside and uses the facilities.

Meanwhile, if a second prospective user arrives at the gas station he finds the toilet locked and therefore unavailable to him. He goes to the service desk but the key is not there because it is in the hands of the current user. When the current user finishes, he unlocks the door and returns the key to the service desk. He does not bother about waiting customers. The service desk gives the key to the waiting customer. If more than one prospective user turns up while the toilet is locked, they must form a queue waiting for the key to the lock. Each thread has no idea who is in the toilet.

Obviously in applying this analogy to Java, a Java thread is a user and the toilet is a block of code which the thread wishes to execute. Java provides a way to lock the code for a thread which is currently executing it using the synchorinized keywokd, and making other threads that wish to use it wait until the first thread is finished. These other threads are placed in the waiting state. Java is NOT AS FAIR as the service station because there is no queue for waiting threads. Any one of the waiting threads may get the monitor next, regardless of the order they asked for it. The only guarantee is that all threads will get to use the monitored code sooner or later.

Finally the answer to your question: the lock could be the key object or the service desk. None of which is a Thread.

However, these are the objects that currently decide whether the toilet is locked or open. These are the objects that are in a position to notify that the bath room is open ("notify") or ask people to wait when it is locked wait.

If the threads were designed to give the lock to one another, then one thread might ‘chose’ a ‘friendly’ thread leading to nepotism.Hence, the wait and notify methods have to be in Object class.Threads borrow keys from JVM and return to JVM.

NOW what is a lock?

Locks are inbuilt, hidden objects in a class. For static synchorinized methods the class object has a lock and for non-staic classes the objects instances themselves are the lock.

That is why while blocking a piece of code (instead of an entire method) we use synchronized(this)

If the same thread has to access various piece of code which are mutually exclusive to modifications then simply create two objects and call them lock1 and lock2 and use these two locks to synchornize.

example. if within the same code there are two areas that have to be synchronized and if the two areas are mutually exclusive then we SHOULD NOT USE this keyword for locking.

In our analogy, if there is a condom vending machine in the toilet, then if an user who does not want to buy condoms is using the bathroom, then the same key will lock the toilet and the vending machine and if there is a person in the queue who wants to use the toilet only to get a condom, then he is unnecessarily locked. In this case the gas station has to use two rooms and two keys. That way using one will not affect the other.

Synchronization :-

Intrinsic lock or monitor lock :-
Every object has an intrinsic lock associated with it. A thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

The Java programming language provides two basic synchronization idioms:
  • Synchronized methods
  • Synchronized statements

Synchronized method:-
To make a method synchronized, simply add the synchronized keyword to its declaration:
public class SynchronizedCounter {
    private int c = 0;
    public synchronized void increment() {
        c++;
    }
}

When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.The changes to the state of the object are visible to all the threads.

Synchronized statements:-
Synchronized statements must specify the object that provides the intrinsic lock
1. If case there are variables which are used together, in this case we can use one lock for synchronization
    public void addName(String name) {
        synchronized(this) {
        lastName = name;
        nameCount++;
        }
        nameList.add(name);
    }
2. If case there are variables which are never used together, in this case we should use separate locks for synchronization
    public class MsLunch {
        private long c1 = 0;
        private long c2 = 0;
        private Object lock1 = new Object();
        private Object lock2 = new Object();
        public void inc1() {
        synchronized(lock1) {
            c1++;
        }
        }
        public void inc2() {
        synchronized(lock2) {
            c2++;
        }
        }
    }
   
Re-entrant synchronization:- This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock
 

No comments:

Post a Comment

SpringBoot Application Event Listeners

When a spring boot application starts few events occurs in below order ApplicationStartingEvent ApplicationEnvironmentPreparedEvent Applicat...