Showing posts with label Threads. Show all posts
Showing posts with label Threads. Show all posts

27 May 2013

How Many Ways We Can Create Threads In Java

In java there are only 2 ways of creating threads. How ever since java1.5 there is one another way to invoke a Thread. The following shows how we can create threads in java.

First Method:-

A class can extend Thread class and overrides the run method of the Thread class.

Example:- 

 public class Murali extends Thread{
     public void run(){
     ==do something here==
    }
  }//class ends here.
Murali a=new Murali();
a.start();

Second Method:-

Writing a custom class which implements Runnable interface and pass this class to the Thread constructor.

Example:-      

 public class Car implements Runnable{
   public void run(){
    ==do something here==
   }
  }

Thread a=new Thread(new Car());
a.start();

Second method is good than first method because only one class can be extended and if you have extended Thread class no other class can be extended.
Since java1.5:-

How ever since java1.5 there is another way to invoke a thread. That is by “ExecutorService”. All these classes are from the “java.util.concurrent” package. There are various ways to create a “ExecutorService” using “Executors” factory class. The following is one of the way to create “ExecutorService”..

ExecutorService es= Executors.newSingleThreadExecutor();
RunnableImpl r = new RunnableImpl();
Future fu=es.submit(r);

using “ExecutorService” methods we can submit eighter Runnable or Callable to the service for execution.

How ever this cannot be said as the new way to create a Thread. It is because ExecutorService internally uses “ThreadFactory” class to create a new thread which internally uses eighter first or second method. So we have to say that there are only two ways to create threads but there is a new way in java1.5 to invoke a thread but not to create a Thread.

How “Thread.join()” works in Java

The join is the instance method in the Thread class. So many people get confused of the function of join. So thought to document the functionality of it. The join functionality awaits the thread to die. Here is how it works with example.

Example:-

public class ThreadJoin {

 public static void main(String[] args)throws Exception {
  Thread a=new Thread(new Mur(),"1");
  Thread b=new Thread(new Mur(),"2");
 
  a.start();
  a.join();
  b.start();
 
  System.out.println("End Of Main Thread");

 }

 private static class Mur implements Runnable{
  public void run() {
              for (int x = 1; x <= 10; x++) {
                       System.out.println("this is thread "
                                       + Thread.currentThread().getName());
                      }
  }
 }//end of the static inner class.
}//end of the main class.

Normally the thread that runs the main method is called main thread. So when main thread starts the other threads it does not stop executing. It starts the other threads and still continues it’s execution. Main thread finishes it’s execution and at the end it waits for the other threads that it created to die. Once the other threads it created dies then the main thread also dies.


Now How Does Join Makes Difference:-

The thread that executes the join on another thread waits (without moving to next instruction) until the thread on which the join is called dies.

In the example the main thread started a new thread by executing start method on Thread object “a” (a.start();). So now the thread “a” (Thread a=new Thread(new Mur(),"1")) starts executing as an individual light weight process. The main thread moves on and executes the next statement that is “a.join();”. The moment that it executes join on thread “a” it goes into a waiting mode, This means it stops executing the next instructions. The main thread invoked “join” (a.join();)on another thread (that is on thread object “a”) so it stops executing and waits until the other thread on which the join is called dies. Once the other thread dies the main thread resumes and starts executing the next instructions.

So the thing that has to be understood is, any thread that invokes join on another thread waits until the thread on which join is called finishes it’s execution.

The Output of the above stated example when “a.join()” is commented:-

this is thread 2
this is thread 1
this is thread 1
End Of Main Thread
this is thread 1
this is thread 2
this is thread 2
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 2
this is thread 1
this is thread 1
this is thread 1
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2


The Output of the above stated example with “a.join()”:-

this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
this is thread 1
End Of Main Thread
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2
this is thread 2

Thread Safety In Java

Thread safety is avoiding thread interference.Thread interference is two or more threads executing a set of operations on the same data concurrently.This causes problem. To avoid this we should make sure that one thread runs at a time and not to allow another thread to run on the same data until it is finish.

This can be achieved in java by synchronization and from java1.5 there is a new way of doing this, that is Atomic actions also called as non blocking algorithms. 

synchronization can be achieved in 2 ways. one is synchronizing the methods and the other is using synchronized blocks.

synchronizing methods:-
synchronized keyword can only be used in front of the methods. The following is the example.

Example:-

public class SynchMethEx {

            private int counter;

           public synchronized void increase(){
                // do some operations and increse the counter
               //to the desired value
           }

          public synchronized void decrease(){
             // do some operations and decrease the counter
             //to the desired value
         }

        public synchronized int getCounter(){
             return counter;
        }
}

in this when a thread enters into one synchronized method of the class it achieves the intrinsic lock of that object so that any other thread cannot enter any of the synchronized methods of that class until the thread comes out of the synchronized method it entered. Once the thread comes out of the synchronized method and before it enters into another synchronized the lock on that object will be released so there is a chance that another thread can attain the lock and perform a synchronized method.

synchronizing the whole method will be a bottleneck for performance. Instead only synchronize the block which needs thread safety.

synchronized blocks:-

The synchronized blocks improves the performance by only synchronizing the block of code which is necessary. The following is the example.

Example:-

public class SynchBlock {

 public static void main(String[] args)throws Exception {
 
  Thread b=new Thread(new Kir(ThreadSync.class),"2");
  Thread c=new Thread(new Kir(ThreadSync.class),"3");
  Thread d=new Thread(new Kir(ThreadSync.class),"4");
 
 
  b.start();
  c.start();
  d.start();

 }

 
 private static class Kir implements Runnable{

         private Object obj;

        public Kir(Object obj){
            this.obj=obj;
       }

        public void run(){
             synchronized(obj){
                  int i=0;
                  while(true){
                     System.out.println("Thread"+Thread.currentThread().getName()+"@"+i);
                      if(i==100)break;
                     i++;
                 }//end of the while loop.
             }//end of the synchronized block.
       }//end of run method.
 }//end of the inner class.

}//end of the main class.

Before the thread enters into the synchronized block it has to obtain intrinsic lock on the object specified in the in the parentheses of the block definition(in the above example the lock on the object it has to attain is “obj”). Once it achieves the lock it will be able to execute the synchronized block. Once the thread is out of the synchronized block the lock on that particular object will be released so that another thread can attain a lock and can execute the synchronized block.

so the above two methods achieve thread safety but there is a problem. when one thread attained intrinsic lock on the object, The other threads that try to attain lock on the same object move to the runnable state and has to be rescheduled and also need to compete for the lock with the other threads who are waiting for the lock on the same object.

So java1.5 came with a solution called Atomic actions or Non Blocking Algorithms.  

Atomic Actions or Non Blocking Algorithms(Since java1.5):-

In concurrent programming an operation (or set of operations) is atomic, linearizable, indivisible or uninterruptible if it appears to the rest of the system to occur instantaneously.Atomicity is a guarantee of isolation from concurrent process. Additionally, atomic operations commonly have a succeed or fail definition — they either successfully change the state of the system, or have no apparent effect.

In programming, an atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.

An atomic action has to happen all at once or none. It is not that thread which is executing the atomic operation need not be in a running state until it completes the action. The atomic action ensures that the effects of it or seen only after the complete execution and if this detects the thread interference it does nothing. It ensures thread safety. It appears like all happened at once

For example the following are the steps involved in atomic operation:-

 Take the value from the shared variable.
  increment the value by one
  set the value back again to the shared variable.
 so the operation has to look like the complete operation had happened at once or instantaneously. so it follows the following algorithm.
 Take the value of the shared variable into another local variable(int i=j).
Add one to it and assign it to another variable(int k=i+1)
Now lock the shared variable(may be at hardware level) and check whether the shared variable still holds the value that it took at the beginning of the operation.
If it is the same then set the increased value(k) to the shared variable (j)  and release the lock so that other threads can perform operation on shared variable.
If it is not the same (suppose while these operations are happening another thread got it’s turn and changed the shared variable value) then nothing happens, it does not change the shared variable value and also releases the lock making the variable available to other threads for operating on it.
So the whole operation looks like it happened at once or not happened at all.

This is how it avoids thread interference and ensures thread safety.

Atomicity is commonly enforced by mutual exclusion, whether at the hardware level building on a cache coherency protocol, or the software level using semaphores or locks. Thus, an atomic operation does not actually occur instantaneously. The benefit comes from the appearance: the system behaves as if each operation occurred instantly, separated by pauses.

In computer science, compare-and-swap (CAS) is an atomic instruction used in multithreading to achieve synchronization. It compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value. This is done as a single atomic operation. The atomicity guarantees that the new value is calculated based on up-to-date information; if the value had been updated by another thread in the meantime, the write would fail. The result of the operation must indicate whether it performed the substitution; this can be done either with a simple Boolean response (this variant is often called compare-and-set), or by returning the value read from the memory location (not the value written to it).

In java
Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
Reads and writes are atomic for all variables declared volatile (including long and double variables).

Since java1.5 Some of the classes in the package “java.util.concurrent” provide atomic methods that do not rely on synchronization.

Atomic variables:-

The “java.util.concurrent.atomic” package defines classes that support atomic operations on single variables. All classes have get and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.

Example:-

import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
    private AtomicInteger c = new AtomicInteger(0);

    public void increment() {
        c.incrementAndGet(); //This is atomic operation. Internally uses CAS.
    }

    public void decrement() {
        c.decrementAndGet(); // this is atomic. Internally uses CAS.
    }

    public int value() {
        return c.get();
    }

}

The Atomic variables also contain CAS methods which perform Atomic operations.

Threads In Brief(java)

 when you want to concurrent tasks threads are the way in java to do it. Thread is a lightweight process which is part of the process. The threads can share memory but they run on their own stack. Every thread has a lifecycle. It will be in different states throughout its life cycle.

Thread Life Cycle:-




New State:-

when Thread object is created (Thread as=new Thread(new RunnableImpl)) it will be in new state. In this state the thread is not alive. From new state they move to runnable state.

Runnable State:-

From new state it moves to runnable state when start() method is called on the thread. Once the start() method is called on the thread,  the thread moves to runnable state. In this state the thread is ready to run and is waiting for the thread scheduler to give him a chance to run. In this state the thread is alive. when thread scheduler gives the thread a chance to run then it moves to running state.

Running State:-

Once the thread scheduler gives a chance to a thread that is in runnable state to run then it moves to running state. This is state that does some action. In this state the thread starts executing its task, that means it starts executing the threads “run()” method. As long as it is in this state it keeps executing until it dies. From this state thread can move back to runnable state or it moves to blocked state or it moves to dead state.

Blocked state:-

If the static method yield() is invoked on the thread the thread moves from running state to runnable state. If the static method sleep() is invoked on the thread then it moves to blocking state from running state for a certain period of time. If method wait() is called in the synchronized code then also the thread moves from running state to blocked state. If Thread has to wait for some input then also it moves to blocked state from running state. The thread is alive in this state.

Once the threads are out of blocked state they move to runnable state.

Dead State:-

If the thread finishes its execution, that means if it completes the “run()” method then it moves to a dead state. Once the thread is dead that cannot be started again but it can be accessed as a normal java object.

Thread priorities are not guaranteed. we can set the priorities but it is not guaranteed that the the thread scheduler gives high priority thread a chance to run immediately. It can pick up any thread. Thread scheduler is platform dependent. It may use different algorithms like “Round Robin” or “Time Slicing” for implementation.

Important Methods In Thread Class:-

 Thread.sleep(long millis):-

when this static method is called the currently executing thread moves to blocked state, i mean it sleeps for at least the specified amount of time. If this is called inside the synchronized code the thread goes to sleep without releasing the lock. It does not release the lock until it finishes the synchronized code.

Thread.yield():-

when this static method is called the currently executing thread moves to runnable state from running state.

Thread.join():-

The thread which executes “join()” method on another thread object will stop executing until the other thread on which “join()” is called finishes its execution, i mean until it is dead.

Thread.interrupt():-

Sends signal to thread to interrupt execution.

Inter Thread Communication:-

Threads communicate with each other by using the following methods that are declared inside the class “Object”. All these methods can be called only inside the synchronized code. Before calling this methods the thread has to attain intrinsic lock on that particular object.

 wait()
notify()
notifyAll()

wait():-

This causes the thread to move to waiting state(blocked state) until another thread notifies it. The thread releases the lock before it enters to blocked state. Here the thread enters to a pool of waiting threads on that particular object.

notiy():-

When this method is called on a particular object, it wakes up a single thread from the pool of threads waiting on that particular object. Choosing the thread is arbitrary.

notifyAll():-

When this method is called on a particular object, it wakes up all the threads in the pool waiting on that particular object.

Example for Inter communication:-

class Q {
   int n;
   boolean valueSet = false;
   synchronized int get() {
      if(!valueSet)
      try {
         wait();
      } catch(InterruptedException e) {
         System.out.println("InterruptedException caught");
      }
      System.out.println("Got: " + n);
      valueSet = false;
      notify();
      return n;
   }

   synchronized void put(int n) {
      if(valueSet)
      try {
         wait();
      } catch(InterruptedException e) {
         System.out.println("InterruptedException caught");
      }
      this.n = n;
      valueSet = true;
      System.out.println("Put: " + n);
      notify();
   }
}// end of class Q

class Producer implements Runnable {
   Q q;
   Producer(Q q) {
      this.q = q;
      new Thread(this, "Producer").start();
   }

   public void run() {
      int i = 0;
      while(true) {
         q.put(i++);
      }
   }
}

class Consumer implements Runnable {
    Q q;
    Consumer(Q q) {
       this.q = q;
       new Thread(this, "Consumer").start();
    }
    public void run() {
       while(true) {
       q.get();
    }
  }
}
public class PCFixed {

   public static void main(String args[]) {
      Q q = new Q();
      new Producer(q);
      new Consumer(q);
      System.out.println("Press Control-C to stop.");
   }
}

Guarded Blocks:-
 a block begins by polling a condition that must be true before the block can proceed.
For Example:-
public void guardedJoy() {
    // Simple loop guard. Wastes
    // processor time. Don't do this!
    while(!joy) {}
    System.out.println("Joy has been achieved!");
    // some more instructions goes here.
}

In the above the complete method is guarded by a polling condition. It makes sure the method does not get executed until the condition is met. Until some other thread sets the “joy” value to “false” the loop keeps polling. This also can be improved by Inter Thread Communication(wait, notify).

Thread Liveness:-

The notion that your program will not lock up and eventually do something useful is called the liveness property.

There are a number of reasons why a multi-threaded program will fail liveness:

      Deadlock
      Starvation and Live Lock

Deadlock:-

Both the threads wait for each other to release the resource for further processing is called deadlock.
Example:-

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n",
            this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s" + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston =  new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

Deadlocks can be avoided by using Explicit locks which are introduced as part of the “java.util.concurrent.locks” package from java1.5.

Explicit Locks:-

Lock objects work very much like the implicit locks used by synchronized code. As with implicit locks, only one thread can own a Lock object at a time. Lock objects also support a wait/notify mechanism, through their associated Condition objects.

The biggest advantage of Lock objects over implicit locks is their ability to back out of an attempt to acquire a lock. The tryLock method backs out if the lock is not available immediately or before a timeout expires (if specified). The lockInterruptibly method backs out if another thread sends an interrupt before the lock is acquired.

solving deadlock using explicit locks:-

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;

public class Safelock {
    static class Friend {
        private final String name;
        private final Lock lock = new ReentrantLock();

        public Friend(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public boolean impendingBow(Friend bower) {
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
                if (! (myLock && yourLock)) {
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            return myLock && yourLock;
        }
           
        public void bow(Friend bower) {
            if (impendingBow(bower)) {
                try {
                    System.out.format("%s: %s has" + " bowed to me!%n", this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }

        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    static class BowLoop implements Runnable {
        private Friend bower;
        private Friend bowee;

        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }
   
        public void run() {
            Random random = new Random();
            for (;;) {
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {}
                bowee.bow(bower);
            }
        }
    }
           

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new BowLoop(alphonse, gaston)).start();
        new Thread(new BowLoop(gaston, alphonse)).start();
    }
}

Starvation:-

If the currently executing thread keeps on executing synchronized methods on the object and if it does block the other threads waiting for monitor lock on the same object for longer time is called starvation.

 Immutable Objects:-

 An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.
 Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

Thread Safety:-

This can be achieved by avoiding thread interference. This can be done by synchronizing methods, synchronizing blocks and Atomic actions.

The java.util.concurrent package includes a number of additions to the Java Collections Framework which can be safely used in concurrent applications.