Thread Join + ScheduledExecutorService not working as expected - java

In the below code snippet, I notice the following sequence of execution. Why is the control going back to the flow outside the someMethod() before completing the activity in the someTask block? Shouldn't it complete everything inside thread2 before moving to the next line of code as thread2.join() has been invoked?
System.out.prinltn("inside someMethod...");
System.out.println("after thread2 .....");
System.out.prinltn("inside someTask......");
public static void main(String args[]) {
Thread thread1 = new Thread(new someclassimplementingRunnable());
thread1.start();
try {
thread1.join();
Thread thread2 = new Thread(new Runnable() {
public void run() {
someMethod();
}
});
thread2.start();
thread2.join();
System.out.println("after thread2 .....");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("outside try-catch");
}
public static synchronized void someMethod(){
System.out.prinltn("inside someMethod...");
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable someTask = () -> {
System.out.prinltn("inside someTask......");
};
executor.scheduleAtFixedRate(someTask , 0, 2, TimeUnit.SECONDS);
}

it is working as expected. you're just expecting the wrong outcome ;)
Thread2 finishes it's work once the executor starts working, and frankly, its a miracle you get to see "inside someTask" at all, as the executor and it tasks will be garbage collected once "someMethod" finishes working. (i.e. the Executor doesn't stay alive outside of someMethod, and there is no blocking operation at the end of someMethod that waits for the executor to finish).
i would even wager that if you run this code enough times, there will be instances when you won't see the line "inside someTask" because of random OS/process scheduling.
there is no line that makes "someMethod" wait, and so Thread2 finishes its work and it passes .join() and you see the print out "after thread2".
also, remember that the Console is not a synchronic output service. when multiple threads send output to the console, its not guaranteed to appear in the same order. so it is not a good indication of the order of events in a multithreaded environment.

I found the solution and actually its pretty simple, checking the condition while(!executor.isTerminated()) does the job. It ensures the next statements are executed only after the executor has done its job.

Related

Not Getting expected result in multi-threaded program

I'm not getting expected result for below program, I was expecting both producer and consumer method should execute in some sequence, but for some reason only producer method is getting executed.
I have two question here :
I'm not able to understand this behaviour.
Joining both thread together in last line of main method is working properly, I'm not able to understand difference between both.
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
Output :
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
The produce() method ends with wait(). So it blocks until some thread notifies it.
The only thread that does that is the consumer thread. But the consumer thread is started by the main method only after the producer thread has ended. And it can't end until it's been notified. So you have a deadlock.
If you join() only after the two threads are started, then the consumer thread can start without having to wait for the producer thread to be finished. That still doesn't make the program correct since
you have no guarantee that the producer thread will execute first
calling wait() at then end is useless
calling wait() out of a loop checking for a condition is incorrect
if you want methods to execute in sequence, using threads is useless. You can do everything from the main thread.
1) A notify() call does not do anything at all. Unless some other thread is already waiting to be notified.
It's up to you to guarantee that any time one of your threads calls wait(), some other thread will notify() the same object some time after the wait() has begun.
Oracle's Guarded Blocks Tutorial does a pretty good job of explaining exactly how o.wait() and o.notify() work, and it explains how to establish that guarantee.
2) There is virtually no reason to do this:
Thread t = new Thread(r);
t.start();
t.join();
Your program will use less CPU, and it will use less memory, and it will accomplish exactly the same thing if you just call r.run() instead. The entire point of threads is to allow different things to happen concurrently, and there is no concurrency if one thread joins a new thread immediately after creating it. The new Thread object is wasted unless you do something like this with it:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait() and notify() are a very low-level means of communicating between threads. Your code will be easier to read and understand if you use higher-level synchronization objects that are built on top of wait() and notify() instead of directly
calling them.
A java.util.concurrent.ArrayBlockingQueue instance would be especially well suited to a "producer/consumer" application.

multithreading - Making threads execute in turns [duplicate]

Can someone help me to understand what Java CountDownLatch is and when to use it?
I don't have a very clear idea of how this program works. As I understand all three threads start at once and each Thread will call CountDownLatch after 3000ms. So count down will decrement one by one. After latch becomes zero the program prints "Completed". Maybe the way I understood is incorrect.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
private CountDownLatch latch;
public Processor(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Started.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
// -----------------------------------------------------
public class App {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0
ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool
for(int i=0; i < 3; i++) {
executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
}
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed.");
}
}
Yes, you understood correctly.
CountDownLatch works in latch principle, the main thread will wait until the gate is open. One thread waits for n threads, specified while creating the CountDownLatch.
Any thread, usually the main thread of the application, which calls CountDownLatch.await() will wait until count reaches zero or it's interrupted by another thread. All other threads are required to count down by calling CountDownLatch.countDown() once they are completed or ready.
As soon as count reaches zero, the waiting thread continues. One of the disadvantages/advantages of CountDownLatch is that it's not reusable: once count reaches zero you cannot use CountDownLatch any more.
Edit:
Use CountDownLatch when one thread (like the main thread) requires to wait for one or more threads to complete, before it can continue processing.
A classical example of using CountDownLatch in Java is a server side core Java application which uses services architecture, where multiple services are provided by multiple threads and the application cannot start processing until all services have started successfully.
P.S.
OP's question has a pretty straightforward example so I didn't include one.
CountDownLatch in Java is a type of synchronizer which allows one Thread to wait for one or more Threads before it starts processing.
CountDownLatch works on latch principle, thread will wait until gate is open. One thread waits for n number of threads specified while creating CountDownLatch.
e.g. final CountDownLatch latch = new CountDownLatch(3);
Here we set the counter to 3.
Any thread, usually main thread of application, which calls CountDownLatch.await() will wait until count reaches zero or it's interrupted by another Thread. All other threads are required to do count down by calling CountDownLatch.countDown() once they are completed or ready to the job. as soon as count reaches zero, the Thread awaiting starts running.
Here the count is get decremented by CountDownLatch.countDown() method.
The Thread which calls the await() method will wait until the initial count reaches to zero.
To make count zero other threads need to call the countDown() method.
Once the count become zero the thread which invoked the await() method will resume (start its execution).
The disadvantage of CountDownLatch is that it's not reusable: once the count become zero it is no longer usable.
It is used when we want to wait for more than one thread to complete its task. It is similar to join in threads.
Where we can use CountDownLatch
Consider a scenario where we have requirement where we have three threads "A", "B" and "C" and we want to start thread "C" only when "A" and "B" threads completes or partially completes their task.
It can be applied to real world IT scenario
Consider a scenario where manager divided modules between development teams (A and B) and he wants to assign it to QA team for testing only when both the teams completes their task.
public class Manager {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
MyDevTeam teamDevA = new MyDevTeam(countDownLatch, "devA");
MyDevTeam teamDevB = new MyDevTeam(countDownLatch, "devB");
teamDevA.start();
teamDevB.start();
countDownLatch.await();
MyQATeam qa = new MyQATeam();
qa.start();
}
}
class MyDevTeam extends Thread {
CountDownLatch countDownLatch;
public MyDevTeam (CountDownLatch countDownLatch, String name) {
super(name);
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
System.out.println("Task assigned to development team " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Task finished by development team " + Thread.currentThread().getName());
this.countDownLatch.countDown();
}
}
class MyQATeam extends Thread {
#Override
public void run() {
System.out.println("Task assigned to QA team");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Task finished by QA team");
}
}
Output of above code will be:
Task assigned to development team devB
Task assigned to development team devA
Task finished by development team devB
Task finished by development team devA
Task assigned to QA team
Task finished by QA team
Here await() method waits for countdownlatch flag to become 0, and countDown() method decrements countdownlatch flag by 1.
Limitation of JOIN:
Above example can also be achieved with JOIN, but JOIN can not be used in two scenarios:
When we use ExecutorService instead of Thread class to create threads.
Modify above example where Manager wants to handover code to QA team as soon as Development completes their 80% task. It means that CountDownLatch allow us to modify implementation which can be used to wait for another thread for their partial execution.
NikolaB explained it very well, However example would be helpful to understand, So here is one simple example...
import java.util.concurrent.*;
public class CountDownLatchExample {
public static class ProcessThread implements Runnable {
CountDownLatch latch;
long workDuration;
String name;
public ProcessThread(String name, CountDownLatch latch, long duration){
this.name= name;
this.latch = latch;
this.workDuration = duration;
}
public void run() {
try {
System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds");
Thread.sleep(workDuration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+ "completed its works");
//when task finished.. count down the latch count...
// basically this is same as calling lock object notify(), and object here is latch
latch.countDown();
}
}
public static void main(String[] args) {
// Parent thread creating a latch object
CountDownLatch latch = new CountDownLatch(3);
new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs
new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs
new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs
System.out.println("waiting for Children processes to complete....");
try {
//current thread will get notified if all chidren's are done
// and thread will resume from wait() mode.
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All Process Completed....");
System.out.println("Parent Thread Resuming work....");
}
}
CoundDownLatch enables you to make a thread wait till all other threads are done with their execution.
Pseudo code can be:
// Main thread starts
// Create CountDownLatch for N threads
// Create and start N threads
// Main thread waits on latch
// N threads completes there tasks are returns
// Main thread resume execution
As mentioned in JavaDoc (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html), CountDownLatch is a synchronization aid, introduced in Java 5. Here the synchronization does not mean restricting access to a critical section. But rather sequencing actions of different threads.
The type of synchronization achieved through CountDownLatch is similar to that of Join.
Assume that there is a thread "M" which needs to wait for other worker threads "T1", "T2", "T3" to complete its tasks
Prior to Java 1.5, the way this can be done is, M running the following code
T1.join();
T2.join();
T3.join();
The above code makes sure that thread M resumes its work after T1, T2, T3 completes its work. T1, T2, T3 can complete their work in any order.
The same can be achieved through CountDownLatch, where T1,T2, T3 and thread M share same CountDownLatch object.
"M" requests : countDownLatch.await();
where as "T1","T2","T3" does countDownLatch.countdown();
One disadvantage with the join method is that M has to know about T1, T2, T3. If there is a new worker thread T4 added later, then M has to be aware of it too. This can be avoided with CountDownLatch.
After implementation the sequence of action would be [T1,T2,T3](the order of T1,T2,T3 could be anyway) -> [M]
This example from Java Doc helped me understand the concepts clearly:
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
Visual interpretation:
Evidently, CountDownLatch allows one thread (here Driver) to wait until a bunch of running threads (here Worker) are done with their execution.
One good example of when to use something like this is with Java Simple Serial Connector, accessing serial ports. Typically you'll write something to the port, and asyncronously, on another thread, the device will respond on a SerialPortEventListener. Typically, you'll want to pause after writing to the port to wait for the response. Handling the thread locks for this scenario manually is extremely tricky, but using Countdownlatch is easy. Before you go thinking you can do it another way, be careful about race conditions you never thought of!!
Pseudocode:
CountDownLatch latch;
void writeData() {
latch = new CountDownLatch(1);
serialPort.writeBytes(sb.toString().getBytes())
try {
latch.await(4, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
}
class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()){//If data is available
byte buffer[] = serialPort.readBytes(event.getEventValue());
latch.countDown();
}
}
}
If you add some debug after your call to latch.countDown(), this may help you understand its behaviour better.
latch.countDown();
System.out.println("DONE "+this.latch); // Add this debug
The output will show the Count being decremented. This 'count' is effectively the number of Runnable tasks (Processor objects) you've started against which countDown() has not been invoked and hence is blocked the main thread on its call to latch.await().
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 2]
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 1]
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 0]
From oracle documentation about CountDownLatch:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset.
A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes.
A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown().
A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.
public void await()
throws InterruptedException
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
If the current count is zero then this method returns immediately.
public void countDown()
Decrements the count of the latch, releasing all waiting threads if the count reaches zero.
If the current count is greater than zero then it is decremented. If the new count is zero then all waiting threads are re-enabled for thread scheduling purposes.
Explanation of your example.
You have set count as 3 for latch variable
CountDownLatch latch = new CountDownLatch(3);
You have passed this shared latch to Worker thread : Processor
Three Runnable instances of Processor have been submitted to ExecutorService executor
Main thread ( App ) is waiting for count to become zero with below statement
latch.await();
Processor thread sleeps for 3 seconds and then it decrements count value with latch.countDown()
First Process instance will change latch count as 2 after it's completion due to latch.countDown().
Second Process instance will change latch count as 1 after it's completion due to latch.countDown().
Third Process instance will change latch count as 0 after it's completion due to latch.countDown().
Zero count on latch causes main thread App to come out from await
App program prints this output now : Completed
package practice;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch c= new CountDownLatch(3); // need to decrements the count (3) to zero by calling countDown() method so that main thread will wake up after calling await() method
Task t = new Task(c);
Task t1 = new Task(c);
Task t2 = new Task(c);
t.start();
t1.start();
t2.start();
c.await(); // when count becomes zero main thread will wake up
System.out.println("This will print after count down latch count become zero");
}
}
class Task extends Thread{
CountDownLatch c;
public Task(CountDownLatch c) {
this.c = c;
}
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
c.countDown(); // each thread decrement the count by one
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Best real time Example for countDownLatch explained in this link CountDownLatchExample
The best option is CyclicBarrier, as per https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
See:
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

Java Threading: Is using interrupt() within run() acceptable to stop a thread when it is finished completing its task?

I have setup a Java Thread class which preforms a particular task of creating a new Process and running it along with various other things.
In the parent class which invokes the Thread I have setup a loop
while(!thread.isActive()) {
...
}
I wanted to know if it is best practices / acceptable to update the run() in the Thread class to issue a interrupt()
run() {
callTask();
interrupt();
}
Update
I could then create a boolean finished field on the Thread and change that to true once the callTask() is completed and have the parent look for
Thread:
run() {
callTask();
finished = true;
}
Parent:
// Start the threads for each Device
for (DeviceRunner deviceRunner : deviceRunners) {
deviceRunner.start();
}
boolean doneProcessingDevices = false;
while (!doneProcessingDevices) {
Set<DeviceRunner> deviceRunnersToRemove = new HashSet<DeviceRunner>();
for (DeviceRunner deviceRunner : deviceRunners) {
if (deviceRunner.isFinishedRunning()) { // check to see if the thread is finished
deviceRunnersToRemove.add(deviceRunner);
}
}
// remove the device runners which are no longer active
deviceRunners.removeAll(deviceRunnersToRemove);
if (deviceRunners.isEmpty()) {
doneProcessingDevices = true;
}
Thread.sleep(1000);
}
Thank you
Just to clarify: you don't have to stop threads manually. When run() completes, the native thread will die and the Thread object will be garbage collected.
If you want your parent to wait until all tasks completed, you can use a CountDownLatch. Initialize the latch with the number of tasks that have to be done. Every time a task finishes, let him invoke countDown(). In the meantime, your parent blocks on await():
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
This MWE demonstrates the basic idea:
int numberOfTasks = 3;
CountDownLatch latch = new CountDownLatch(numberOfTasks);
while (numberOfTasks-- > 0) {
new Thread(() -> {
try {
// Do stuff.
System.out.println("Done.");
} finally {
latch.countDown();
}
}).start();
}
try {
latch.await();
System.out.println("All tasks finished.");
} catch (InterruptedException e) { /* NOP */ }
You won't see All tasks finished. before each task has printed Done..
I believe what you are really looking for is Thread.join method. Copying from Oracle tutorial
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing, t.join()
causes the current thread to pause execution until t's thread terminates

What is the difference between setting the priority for the main thread or not?

I have this Question :
Create and run a thread that writes "Hello friends" on screen. The main Thread waits for it only 500 milliseconds. Then run the program again after you give the created Thread lower priority than the main Thread. This time, the main Thread should wait for it 10 milliseconds. Do you notice anything? Why?
I want to know the difference that made by Thread.setPriority(n)
first code and second get the same output
first code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
seconde code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
the main Thread should wait for it 10 milliseconds
That's not what your code does. The join should be in the main thread, not in the newly created thread:
Thread2 myThread = new Thread2();
myThread.start();
myThread.join(10);
I assume the whole idea of this exercise is to see the difference between two threads with different priorities. Giving a thread a lower priority may delay its scheduled execution. When the main thread waits for a smaller duration for the new thread to finish, the outputs of the two threads may interleave since the main thread may continue to reach the System.out before the second thread does.
The documentation of the Thread class explains what a thread priority is:
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
In general, don't extend Thread, you should wrap a Runnable instead.
The Thread priority is
just a hint, the OS can and does ignore it if you don't have the right permissions.
It will only matter if you don't have free CPU. If you have free CPU every thread which wants to run can run.
it really won't matter if you are putting your thread to sleep. e.g. a join.
The only difference it could make is when your machine is very busy, it would take a little longer to wake up from the sleep. e.g. instead of taking say 500 to 501 ms to do the join, it might take 510 ms sometimes.
how can I use join method ?
The purpose of join is to wait for another thread to finish up to some time limit. If you join on yourself, this is effectively the same as Thread.sleep I suggest using Thread.sleep instead as this is less confusing.
First, from the documentation for Thread:
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
So when you have two Thread instances, lets say the current one and a new one, you can cause the current thread to wait for the new one to die:
final Thread t = new Thread(() -> System.out.println("Test"));
t.start();
t.join();
So now our current thread (the one creating t) will wait for t to die, then continue. This method makes an asynchronous task synchronous.
Now, what does calling join in a Thread do? Well, it means that the thread will wait for itself to die. This is the same as TimeUnit.MILLISECONDS.sleep().
So what does your code actually do?
Well, main calls the following code:
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
There is nothing here that makes main wait for anything, main dies.
Now your Thread2 (terrible name for a class) does the following:
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
So it sets its own priority, it then waits for 500 milliseconds for itself to die. Obviously it doesn't die in that time. It then prints.
TL;DR: setPriority does next to nothing in this code
One further note, do not extends Thread, use a Runnable.

How is CountDownLatch used in Java Multithreading?

Can someone help me to understand what Java CountDownLatch is and when to use it?
I don't have a very clear idea of how this program works. As I understand all three threads start at once and each Thread will call CountDownLatch after 3000ms. So count down will decrement one by one. After latch becomes zero the program prints "Completed". Maybe the way I understood is incorrect.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
private CountDownLatch latch;
public Processor(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Started.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
// -----------------------------------------------------
public class App {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0
ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool
for(int i=0; i < 3; i++) {
executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
}
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed.");
}
}
Yes, you understood correctly.
CountDownLatch works in latch principle, the main thread will wait until the gate is open. One thread waits for n threads, specified while creating the CountDownLatch.
Any thread, usually the main thread of the application, which calls CountDownLatch.await() will wait until count reaches zero or it's interrupted by another thread. All other threads are required to count down by calling CountDownLatch.countDown() once they are completed or ready.
As soon as count reaches zero, the waiting thread continues. One of the disadvantages/advantages of CountDownLatch is that it's not reusable: once count reaches zero you cannot use CountDownLatch any more.
Edit:
Use CountDownLatch when one thread (like the main thread) requires to wait for one or more threads to complete, before it can continue processing.
A classical example of using CountDownLatch in Java is a server side core Java application which uses services architecture, where multiple services are provided by multiple threads and the application cannot start processing until all services have started successfully.
P.S.
OP's question has a pretty straightforward example so I didn't include one.
CountDownLatch in Java is a type of synchronizer which allows one Thread to wait for one or more Threads before it starts processing.
CountDownLatch works on latch principle, thread will wait until gate is open. One thread waits for n number of threads specified while creating CountDownLatch.
e.g. final CountDownLatch latch = new CountDownLatch(3);
Here we set the counter to 3.
Any thread, usually main thread of application, which calls CountDownLatch.await() will wait until count reaches zero or it's interrupted by another Thread. All other threads are required to do count down by calling CountDownLatch.countDown() once they are completed or ready to the job. as soon as count reaches zero, the Thread awaiting starts running.
Here the count is get decremented by CountDownLatch.countDown() method.
The Thread which calls the await() method will wait until the initial count reaches to zero.
To make count zero other threads need to call the countDown() method.
Once the count become zero the thread which invoked the await() method will resume (start its execution).
The disadvantage of CountDownLatch is that it's not reusable: once the count become zero it is no longer usable.
It is used when we want to wait for more than one thread to complete its task. It is similar to join in threads.
Where we can use CountDownLatch
Consider a scenario where we have requirement where we have three threads "A", "B" and "C" and we want to start thread "C" only when "A" and "B" threads completes or partially completes their task.
It can be applied to real world IT scenario
Consider a scenario where manager divided modules between development teams (A and B) and he wants to assign it to QA team for testing only when both the teams completes their task.
public class Manager {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
MyDevTeam teamDevA = new MyDevTeam(countDownLatch, "devA");
MyDevTeam teamDevB = new MyDevTeam(countDownLatch, "devB");
teamDevA.start();
teamDevB.start();
countDownLatch.await();
MyQATeam qa = new MyQATeam();
qa.start();
}
}
class MyDevTeam extends Thread {
CountDownLatch countDownLatch;
public MyDevTeam (CountDownLatch countDownLatch, String name) {
super(name);
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
System.out.println("Task assigned to development team " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Task finished by development team " + Thread.currentThread().getName());
this.countDownLatch.countDown();
}
}
class MyQATeam extends Thread {
#Override
public void run() {
System.out.println("Task assigned to QA team");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Task finished by QA team");
}
}
Output of above code will be:
Task assigned to development team devB
Task assigned to development team devA
Task finished by development team devB
Task finished by development team devA
Task assigned to QA team
Task finished by QA team
Here await() method waits for countdownlatch flag to become 0, and countDown() method decrements countdownlatch flag by 1.
Limitation of JOIN:
Above example can also be achieved with JOIN, but JOIN can not be used in two scenarios:
When we use ExecutorService instead of Thread class to create threads.
Modify above example where Manager wants to handover code to QA team as soon as Development completes their 80% task. It means that CountDownLatch allow us to modify implementation which can be used to wait for another thread for their partial execution.
NikolaB explained it very well, However example would be helpful to understand, So here is one simple example...
import java.util.concurrent.*;
public class CountDownLatchExample {
public static class ProcessThread implements Runnable {
CountDownLatch latch;
long workDuration;
String name;
public ProcessThread(String name, CountDownLatch latch, long duration){
this.name= name;
this.latch = latch;
this.workDuration = duration;
}
public void run() {
try {
System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds");
Thread.sleep(workDuration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+ "completed its works");
//when task finished.. count down the latch count...
// basically this is same as calling lock object notify(), and object here is latch
latch.countDown();
}
}
public static void main(String[] args) {
// Parent thread creating a latch object
CountDownLatch latch = new CountDownLatch(3);
new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs
new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs
new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs
System.out.println("waiting for Children processes to complete....");
try {
//current thread will get notified if all chidren's are done
// and thread will resume from wait() mode.
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All Process Completed....");
System.out.println("Parent Thread Resuming work....");
}
}
CoundDownLatch enables you to make a thread wait till all other threads are done with their execution.
Pseudo code can be:
// Main thread starts
// Create CountDownLatch for N threads
// Create and start N threads
// Main thread waits on latch
// N threads completes there tasks are returns
// Main thread resume execution
As mentioned in JavaDoc (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html), CountDownLatch is a synchronization aid, introduced in Java 5. Here the synchronization does not mean restricting access to a critical section. But rather sequencing actions of different threads.
The type of synchronization achieved through CountDownLatch is similar to that of Join.
Assume that there is a thread "M" which needs to wait for other worker threads "T1", "T2", "T3" to complete its tasks
Prior to Java 1.5, the way this can be done is, M running the following code
T1.join();
T2.join();
T3.join();
The above code makes sure that thread M resumes its work after T1, T2, T3 completes its work. T1, T2, T3 can complete their work in any order.
The same can be achieved through CountDownLatch, where T1,T2, T3 and thread M share same CountDownLatch object.
"M" requests : countDownLatch.await();
where as "T1","T2","T3" does countDownLatch.countdown();
One disadvantage with the join method is that M has to know about T1, T2, T3. If there is a new worker thread T4 added later, then M has to be aware of it too. This can be avoided with CountDownLatch.
After implementation the sequence of action would be [T1,T2,T3](the order of T1,T2,T3 could be anyway) -> [M]
This example from Java Doc helped me understand the concepts clearly:
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
Visual interpretation:
Evidently, CountDownLatch allows one thread (here Driver) to wait until a bunch of running threads (here Worker) are done with their execution.
One good example of when to use something like this is with Java Simple Serial Connector, accessing serial ports. Typically you'll write something to the port, and asyncronously, on another thread, the device will respond on a SerialPortEventListener. Typically, you'll want to pause after writing to the port to wait for the response. Handling the thread locks for this scenario manually is extremely tricky, but using Countdownlatch is easy. Before you go thinking you can do it another way, be careful about race conditions you never thought of!!
Pseudocode:
CountDownLatch latch;
void writeData() {
latch = new CountDownLatch(1);
serialPort.writeBytes(sb.toString().getBytes())
try {
latch.await(4, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
}
class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()){//If data is available
byte buffer[] = serialPort.readBytes(event.getEventValue());
latch.countDown();
}
}
}
If you add some debug after your call to latch.countDown(), this may help you understand its behaviour better.
latch.countDown();
System.out.println("DONE "+this.latch); // Add this debug
The output will show the Count being decremented. This 'count' is effectively the number of Runnable tasks (Processor objects) you've started against which countDown() has not been invoked and hence is blocked the main thread on its call to latch.await().
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 2]
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 1]
DONE java.util.concurrent.CountDownLatch#70e69696[Count = 0]
From oracle documentation about CountDownLatch:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset.
A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes.
A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown().
A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.
public void await()
throws InterruptedException
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
If the current count is zero then this method returns immediately.
public void countDown()
Decrements the count of the latch, releasing all waiting threads if the count reaches zero.
If the current count is greater than zero then it is decremented. If the new count is zero then all waiting threads are re-enabled for thread scheduling purposes.
Explanation of your example.
You have set count as 3 for latch variable
CountDownLatch latch = new CountDownLatch(3);
You have passed this shared latch to Worker thread : Processor
Three Runnable instances of Processor have been submitted to ExecutorService executor
Main thread ( App ) is waiting for count to become zero with below statement
latch.await();
Processor thread sleeps for 3 seconds and then it decrements count value with latch.countDown()
First Process instance will change latch count as 2 after it's completion due to latch.countDown().
Second Process instance will change latch count as 1 after it's completion due to latch.countDown().
Third Process instance will change latch count as 0 after it's completion due to latch.countDown().
Zero count on latch causes main thread App to come out from await
App program prints this output now : Completed
package practice;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch c= new CountDownLatch(3); // need to decrements the count (3) to zero by calling countDown() method so that main thread will wake up after calling await() method
Task t = new Task(c);
Task t1 = new Task(c);
Task t2 = new Task(c);
t.start();
t1.start();
t2.start();
c.await(); // when count becomes zero main thread will wake up
System.out.println("This will print after count down latch count become zero");
}
}
class Task extends Thread{
CountDownLatch c;
public Task(CountDownLatch c) {
this.c = c;
}
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
c.countDown(); // each thread decrement the count by one
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Best real time Example for countDownLatch explained in this link CountDownLatchExample
The best option is CyclicBarrier, as per https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
See:
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

Categories

Resources