Thursday, 9 February 2017

THREADGROUP IN JAVA

Based on the functionality we can group threads as a single unit which is nothing but ThreadGroup. ThreadGroup provides a convenient way to perform common operations for all the Threads belonging to a particular Group. We can create a ThreadGroup by using the following constructor.
§  ThreadGroup g = new ThreadGroup(String groupName);

We can attach a thread to a ThreadGroup by using the following constructor Thread class.
§  Thread t = new Thread(ThreadGroup g,String ThreadName);

Example –
public class ThreadGroup1 implements Runnable{
          @Override
          public void run() {
                   System.out.println(Thread.currentThread().getName()+", "+Thread.currentThread().getPriority()+", "+Thread.currentThread().getThreadGroup());
          }
          public static void main(String[] args) {
                   ThreadGroup1 group = new ThreadGroup1();
                   ThreadGroup tg = new ThreadGroup("Groupthread");
                   Thread t1 = new Thread(tg,group,"t1");
                   t1.start();
                   Thread t2 = new Thread(tg,group,"t2");
                   t2.setPriority(10);
                   t2.start();
          }
}

Output –
t1, 5, java.lang.ThreadGroup[name=Groupthread,maxpri=10]
t2, 10, java.lang.ThreadGroup[name=Groupthread,maxpri=10]


Example –
public class ThreadGroup1 extends Thread{      
          @Override
          public String toString() {
                   return "ThreadGroup1["+getName()+", "+getPriority()+", "+getThreadGroup()+"]";
          }
          public static void main(String[] args) {
                   Thread t1 = new Thread();
                   System.out.println(t1);
                   Thread t2 = new Thread("CMP");
                   System.out.println(t2);
                   Thread t3 = Thread.currentThread();
                   System.out.println(t3);
                   t3.setPriority(9);
                   System.out.println(t3);
                   Thread t4 = new Thread();
                   System.out.println(t4);
          }
}

Output –
Thread[Thread-0,5,main]
Thread[CMP,5,main]
Thread[main,5,main]
Thread[main,9,main]
Thread[Thread-1,9,main]

DEADLOCK AND SYNCHRONIZATION IN JAVA

If a threads are waiting for each other forever, then such type of situation is called Deadlock. There is no resolution technique for deadlock but several prevention techniques are possible.

public class DeadlockDemo{
          public static void main(String[] args) {
                   final String resource1 = "Java";
                   final String resource2 = "Python";
                   Thread t1 = new Thread(){
                             public void run(){
                                      synchronized(resource1)
                                      {
                                                System.out.println("Thread t1 holds resource1");
                                                try{
                                                          Thread.sleep(100);
                                                }
                                                catch(Exception e){}
                                     
                                      synchronized(resource2)
                                      {
                                                System.out.println("Thread t1 holds resource2");
                                      }
                                      }
                             }
                   };
                   Thread t2 = new Thread(){
                             public void run(){
                                      synchronized(resource2)
                                      {
                                                System.out.println("Thread t2 holds resource2");
                                                try{
                                                          Thread.sleep(100);
                                                }
                                                catch(Exception e){}
                                     
                                      synchronized(resource1)
                                      {
                                                System.out.println("Thread t2 holds resource1");
                                      }
                                      }
                             }
                   };
                   t1.start();
                   t2.start();
          }
}

Output –
Thread t2 holds resource2
Thread t1 holds resource1

Note – In the above example it reach to deadlock as t1 is holding resource1 and t2 is holding resource2, but still both are requesting the resource hold by others.


Synchronized – This keyword is the reason why programs enter into deadlock. Hence by using synchronized keyword we have to handle program execution carefully.

Example –
class Demo{
          int count;
          public void increment()
          {
                   count++;
          }
}
public class SyncDemo {
          public static void main(String[] args) throws InterruptedException {
                   Demo c = new Demo();
                   Thread t1 = new Thread(()->{
                             for(int i=0;i<100;i++)
                             {
                                      c.increment();
                             }
                   });
                   Thread t2 = new Thread(()->{
                             for(int i=0;i<100;i++)
                             {
                                      c.increment();
                             }
                   });
                   t1.start();
                   t1.join();
                   t2.start();
                   System.out.println(c.count);
          }
}

Note – In the above example, as we are supposed to get the value of count as 200 but all the time we will get some random values between within 200. Because at some particular time when t1 holds the resource the same resource is being hold by t2, so it cannot update the exact value. So to overcome with this kind of problem, where at a particular time only one thread should invoke a particular method. Then we should make that method synchronized which gives the facility not to hold resource by many threads at a particular time. One thread releases the resource then only other thread occupies it.

Example –
class Demo{
          int count;
          public synchronized void increment()
          {
                   count++;
          }
}
public class SyncDemo {
          public static void main(String[] args) throws InterruptedException {
                   Demo c = new Demo();
                   Thread t1 = new Thread(()->{
                             for(int i=0;i<100;i++)
                             {
                                      c.increment();
                             }
                   });
                   Thread t2 = new Thread(()->{
                             for(int i=0;i<100;i++)
                             {
                                      c.increment();
                             }
                   });
                   t1.start();
                   t1.join();
                   t2.start();
                   System.out.println(c.count);
          }
}

Output –
200


Synchronized is the keyword applicable only for methods and the blocks, but not for variables and class. If a method or block is declared as synchronized, then at a time only one method is allowed to execute. The main advantage of synchronized keyword is we can resolve data inconsistency problems. The main disadvantage of synchronized keyword is – It increases waiting time of the threads and creates performance problems on it. Hence, if there is no specific requirement then it is never recommended to use synchronized keyword.

Every object in java has a unique lock. Internally synchronization concept is implemented by using lock concept. If a thread wants to execute any synchronized method on the given object, first it has to get the lock of that object. Once a thread gets the lock, then it allows execution of any synchronized method on that object. Once a synchronized method execution is complete, then thread releases the lock automatically. While a thread is executing synchronized method on the given object, then the remaining threads aren’t allowed to execute, any synchronized method simultaneously. The remaining threads are allowed to execute any non synchronized method simultaneously. Lock concept is implemented based on object and not on method.

Example –
class Display
{
          public synchronized void wish(String name)
          {
                   for(int i=0;i<5;i++)
                   {
                             System.out.println("Welcome to CMP");
                             try{
                                      Thread.sleep(1000);
                             }
                             catch(Exception e){}
                   }
                   System.out.println(name);
          }
}
class MyThread4 extends Thread{
          Display d;
          String name;
          public MyThread4(Display d,String name)
          {
                   this.d=d;
                   this.name=name;
          }
          public void run()
          {
                   d.wish(name);
          }
}
public class SyncDemo {
          public static void main(String[] args) throws InterruptedException {
                   Display d = new Display();
                   MyThread4 mt1 = new MyThread4(d, "cmp");
                   MyThread4 mt2 = new MyThread4(d, "rakesh");
                   mt1.start();
                   mt2.start();                  
          }
}

Output –
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
rakesh
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
cmp