0

I am very new to Java Multithreading . Trying to learn countdownlatch and executor in Java threading and implemented the following code-

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorBasicFramework {


    class MyThread extends Thread{

        int iCount ; String name;
        CountDownLatch latch;

        public MyThread(int iCount, String name, CountDownLatch latch) {
            super();
            this.iCount = iCount;
            this.name = name;
            this.latch = latch;         
        }

        @Override
        public void run() {
            for(int i=0;i<10;i++){
                System.out.println(name+" Printing .... "+ ++iCount+" L "+latch.getCount());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }
            latch.countDown();

        }

    }

    public ExecutorBasicFramework() {
        createThread();
    }


    private void createThread() {
        ExecutorService exec = Executors.newFixedThreadPool(10);
        CountDownLatch latch = new CountDownLatch(10);
        for(int i=0;i<10;i++){          
            MyThread thread = new MyThread(i*10, ""+i,latch);
            exec.execute(thread);

            try {
                latch.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        exec.shutdownNow();     

    }

    public static void main(String[] args) {
        new ExecutorBasicFramework();
    }

}

The output coming is as -

0 Printing .... 1 L 10
0 Printing .... 2 L 10
0 Printing .... 3 L 10
0 Printing .... 4 L 10
0 Printing .... 5 L 10
0 Printing .... 6 L 10
0 Printing .... 7 L 10
0 Printing .... 8 L 10
0 Printing .... 9 L 10
0 Printing .... 10 L 10

and then the flow is like keep on waiting. My expected output is like above but after printing 0 , it should print similar output for 1 till 9 and then the program should be stopped.

I think the countdownlatch is waiting and waiting and its not going to increment the next counter of executor. So I am unable to get the expected output. I am expecting output like -

0 Printing .... 1 L 10
0 Printing .... 2 L 10
0 Printing .... 3 L 10
0 Printing .... 4 L 10
0 Printing .... 5 L 10
0 Printing .... 6 L 10
0 Printing .... 7 L 10
0 Printing .... 8 L 10
0 Printing .... 9 L 10
0 Printing .... 10 L 10


1 Printing .... 11 L 9
1 Printing .... 12 L 9
1 Printing .... 13 L 9
1 Printing .... 14 L 9
1 Printing .... 15 L 9
1 Printing .... 16 L 9
1 Printing .... 17 L 9
1 Printing .... 18 L 9
1 Printing .... 19 L 9
1 Printing .... 20 L 9

and So on ... 
2 Printing .... 21 L 8
2 Printing .... 22 L 8
2 Printing .... 23 L 8

with each decrement counter of latch , the next thread is pool must execute a count till 10. and then again it must decrease the latch counter and again the process repeats till the Thread 9 completes the same

Please suggest some input .

1
  • Are you trying to wait for all of the jobs to finish? What's the goal here? Commented Feb 26, 2013 at 17:46

3 Answers 3

3

So you are configuring a count down value of 10 new CountDownLatch(10) but your code is only decrementing it once per thread. After you fork just 1 thread, you then wait for the latch but it is sitting at 9.

MyThread thread = new MyThread(i*10, ""+i,latch);
exec.execute(thread);
latch.await();

Not sure what you intended but maybe the latch.countDown(); should be inside the for loop in the thread?

for(int i=0;i<10;i++) {
   ...
   // if you want the latch to count-down 10 times, it should be inside the loop
   latch.countDown();
}
// it should not go here, outside the loop

If the goal is to wait for all of the jobs to finish, you can do that with the ExecutorService.awaitTermination(...) method:

// submit jobs in loop
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

Also, you should not be extending Thread in your MyThread class. You should be implementing Runnable. The only reason why your code works is that Thread also implements Runnable but MyThread should not be a Thread. The ExecutorService takes a Runnable or a Callable, not a Thread. It manages the threads for you internally to the service.

Sign up to request clarification or add additional context in comments.

2 Comments

@Gray must have said this a million times here :)
No way @RalfH. 100k tops! ;-)
1

If your intent is to use the CountDownLatch to have the main() method wait until all threads have executed, then you should move the latch.await() outside the loop that submits the threads. Also, you should not eat the InterruptedException without setting the interrupted flag again. (see this article).

The correction would look like this :

for(int i=0;i<10;i++){          
    MyThread thread = new MyThread(i*10, ""+i,latch);
    exec.execute(thread);
}
try {
    latch.await();
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

While this will certainly work, the Latch is suboptimal way to wait for the execution of a Runnable on another thread, when using an ExecutorService. If you use submit() rather than execute() you can use the Future returned by submit() to wait for the completion of the submitted Runnable by calling get() on it.

Comments

0

Thanks all for inputs. I found one more easy solution to get what I expected. I just used Executors.newSingleThreadExecutor();as it already ensures that all tasks will be guaranteed to be implemented sequentially.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.