1

I was trying to understand the CountDownLatch usage, following is the code I am using here,

DecrementRunnable.java

    package com.nirjhar.java.countdownlatchexample;

    import java.util.concurrent.CountDownLatch;

    public class DecrementRunnable implements Runnable {

    private String name;
    private CountDownLatch cdl;

    public DecrementRunnable(String name, CountDownLatch cdl) {
    this.name=name;
    this.cdl=cdl;
    }

    @Override
    public void run() {
        System.out.println("in run method");
    for (int i = 0; i < 6; i++) {
        cdl.countDown();
        System.out.println("counting down "+cdl.getCount());
    }
    //cdl.notifyAll();
    System.out.println("Notified to all");
    }
}

CountDownDemoThread.java

package com.nirjhar.java.countdownlatchexample;

import java.util.concurrent.CountDownLatch;

public class CountDownDemoThread extends Thread {

    private CountDownLatch cdl;

    public CountDownDemoThread(String name, CountDownLatch cdl) {
        this.cdl=cdl;
        setName(name);
    }

    @Override
    public synchronized void start() {

        System.out.println("Task completed ... waiting for other thread to complete their task");
        try {
            cdl.await();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        System.out.println("Continuing my tasks ..");
    }
}

Main Program,

package com.nirjhar.java.countdownlatchexample;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args)
    {
        CountDownLatch cdl=new CountDownLatch(6);
        Thread tDecrementThread=new Thread(new DecrementRunnable("Runnable", cdl));
        CountDownDemoThread cddt=new CountDownDemoThread("thread", cdl);        
        cddt.start();   
        System.out.println("thread 1 started");     
        tDecrementThread.start();
    }
}

In this main program, i was expecting this line "thread 1 started" should get printed once the thread one is started, But here main thread is blocked because of the wait statement in cdl.await() statement in cddt thread. Just wanted to know what is the reason behind this?

2 Answers2

3

In your CountDownThread class, I think you wanted to override run() method instead of start

Instead of

public synchronized void start() {

try with

public void run() {


Reason why the

wait statement in cdl.await() statement in cddt thread. Just wanted to know what is the reason behind this?

In this case, you have overridden the start method of Thread and so it no longer spawns a thread to execute the code as it does normally.

So there is no thread that gets spawned and infact the main thread is calling the cd1.await() instead of cd1 thread (that you wanted). And that is why the main thread is blocked.

0

I think you should have to go through the concept of thread synchronization and thread priority.

1.Thread Priority:

Every thread in java has some priority it may be default priority generated by jvm or customized priority provide by programmer The valid rang of thread priority is 1 to 10 where 1 is min priority and 10 is max priority Thread class defines the following constants to represent some standards priorities:

1.Thread.MIN_PRIORITY---------------1

2.Thread.NORM_PRIORITY------------5

3.Thread.MAX_PRIORITY-------------10

Thread scheduler will use priority while allocating processor the thread which is having highest priority will get the chance first If two threads having same priority then we can’t expect exact execution order it depends on thread scheduler

Thread class defines the following method to get and set priority of a thread:

1.public final int getPriority()

2.public final void setPriority(int p)

Note:allowed values range from 1 to 10 otherwise we wil get run time exception IllegalArgumentException

Ex:t.setPriority(7): valid

t.setPriority(17):IllegalArgumentException

----------------------------------------Default Priority--------------------------------------

The Default priority only for the main thread is 5 but for all remaining threads default priority will be inherited from parent to child that is whatever priority parent thread has the same priority will be there for the child thread

--------------------------Customized Priority-------------------------------------------------

   class Mythread extends Thread
      {
        public void run()
        {
          for(int i=0;i<=5;i++)
          {
           System.out.println("child thread........");
           }
       }

     }
  public class ThreadDemo
   {
  public static void main(String arg[])
  {
      Mythread t=new Mythread();
     //   t.setPriority(10);----------(1)
      t.start();

       for(int i=0;i<=5;i++)
        {
           System.out.println("main thread........");
        }

     }
  }

If we are commenting line one then both main and child thread have same priority 5 and hence we can’t expect execution order and exact output If are not commenting line 1 then main thread has a priority 5 and child thread has a priority hence child thread will get the chance first followed by main thread in this case the output is:

    Child thread……….

    Child thread……….

    Child thread……….

    Child thread……….

    Child thread……….

    Main thread……….

    Main thread……….

    Main thread……….

    Main thread……….

    Main thread……….

   [NOTE: some platforms won’t provide proper support for thread priority]

2.Synchronization:

Synchronized is the modifier applicable only for method and blocks but not for classes and variables.

If a 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 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 main advantage of synchronized keyword is we can resolve data inconsistency problems but the main disadvantage of synchronized keyword is it increases waiting time of threads and it creates performance problem hence if there is no specific requirement then it is not recommended to use synchronized keyword.

Internally Synchronization concept is implemented by using lock, every object in java has a unique lock.

Whenever we are using synchronized keyword then only lock concept will come into the picture.

If a thread wants to execute synchronized method on the given object first it has to get lock of that object .

once thread got the lock then it is allowed to execute any synchronized method on that object.

Once a method execution completes automatically thread releases lock. Acquiring and releasing lock internally takes care by jvm and a programmer not responsible for this activity

While a thread executing synchronized method on the given object the remaining threads are not allowed to execute any synchronized method simultaneously on the same object, but remaining threads are allowed to execute non-synchronized methods simultaneously

Example:

Class X
{
  synchronized void m1() {}
  synchronized void m2() {}
   public void m3(){}


  }

In the above example assume thread T1 start execution of m1() because T1 access lock first from jvm, if at a same time thread T2 came to execute m1() method and thread T3 came to execute m2() method, that time both thread T2 and T3 will be waiting state until T1 thread releasing lock.

if thread T4 came to execute m3() method it will execute method m3() directly because it is not the synchronized method. Lock concept is implemented based on object but not based on method

NOTE: remember for every object there are two area’s:

1.Synchronized area.

2.Non-Synchronized area.

 Class X 

{

   Synchronized();

{

   Where ever we are performing update operation           
  ( Add/remove/delete/replace).

   That is  Where state of object changing.

}

 Non-synchronized()

{

  Where ever state of object won’t be changed, like only read    
 operation is performed.


  }



 }

Example: Programmatic approach:

  class Display{

    public synchronized void wish(String name){

        for(int i=1;i<=5;i++){
           System.out.print("Good Morning:");

            try{
                 Thread.sleep(2000);
              }

            catch(InterruptedException e){
                 System.out.println("i got Interrupted");

              }

                  System.out.println(name);
          }

      }

}


  class ThreadDemo extends Thread
   {

     Display d;
     String name;
  public ThreadDemo(Display d,String name){

           this.d=d;
           this.name=name;

        }
  public void run(){
         d.wish(name);
      }


}


public class SynchronizedDemo

{

    public static void main(String arg[]){

         Display d=new Display();
         ThreadDemo t1=new ThreadDemo(d,"Avadhoot");
         ThreadDemo t2=new ThreadDemo(d,"Abhishek");
         ThreadDemo t3=new ThreadDemo(d,"Rinkesh");
         ThreadDemo t4=new ThreadDemo(d,"Kushal");
         t1.start();
         t2.start();
         t3.start();
         t4.start();
    }


}

[NOTE: If we are not declaring wish(String name) method as synchronized then all thread will be executed simultaneously and hence we will get irregular output.

If we declare wish(String name ) method as synchronized then at a time only one thread is allowed to execute wish (String name) method on the given Display(class) object hence we will get regular output.]

CASE STUDY:

 public class SynchronizedDemo

 {

     public static void main(String arg[])

     {        
            Display d1=new Display();
            Display d2=new Display();
            Display d3=new Display();
            Display d4=new Display();
         ThreadDemo t1=new ThreadDemo(d1,"Avadhoot");
         ThreadDemo t2=new ThreadDemo(d2,"Abhishek");
         ThreadDemo t3=new ThreadDemo(d3,"Rinkesh");
         ThreadDemo t4=new ThreadDemo(d4,"Kushal");
         t1.start();
         t2.start();
         t3.start();
         t4.start();

     }

  }

Even though wish(String name) method is synchronized we will get irregular output because threads are operating on different java objects

Conclusion:

If multiple threads are operating on same java object then synchronization is required.

If a multiple threads are operating on multiple java object then synchronization is not required.


*Class Level Lock:

Every class in java has a unique lock which is nothing but class level lock.

If a thread want’s to execute a static synchronized method then thread required class level lock.

Once a thread got class level lock then it is allowed to execute any static synchronized method of that class.

Once a method execution completes automatically thread releases lock While a thread executing static synchronized method the remaining threads are not allowed to execute any static synchronized method of that class simultaneously but remaining threads are allowed to execute the following methods simultaneously:

  1. Normal static method.

  2. Synchronized instance method.

  3. Normal instance method.

For example:

   Class X
    {
     static synchronized m1(){}
     static synchronized m2(){}
     static m3(){}
     synchronized m4(){}
    m5(){}

   }
avadhoot
  • 377
  • 1
  • 3
  • 9