Why does ThreadPool interrupts its workers, when thread interrupted? - java

Please, look at this example. I take it from my production project. Webserver receive a command and starts new Thread which starts calculations via TheadPool. When user want to end calculations, he send another command which interrupts this new Thread, and workers of ThreadPool are shuting down. It's working fine, but I don't understand why.
public static void main(String[] args) throws Throwable {
final ExecutorService p = Executors.newFixedThreadPool(2);
System.out.println("main say: Hello, I'm Main!");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + " say: Starting monitor");
Thread monitor = new Thread(new Runnable() {
#Override
public void run() {
try {
while(true) {
Thread.sleep(1500);
System.out.println(Thread.currentThread().getName() + " say: I'm still here...hahahahah");
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: Bye for now!");
}
}
},"monitor");
monitor.setDaemon(true);
monitor.start();
List<Callable<Integer>> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
threads.add(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " say: Hello!");
try {
for (int c = 0; c < 5; c++) {
System.out.println(Thread.currentThread().getName() + " say: " + c);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: I'm interrupted :(");
}
System.out.println(Thread.currentThread().getName() + " say: Bye!");
return 0;
}
});
}
System.out.println(Thread.currentThread().getName() + " say: Starting workers");
try {
p.invokeAll(threads);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: I'm interrupted :(");
}
System.out.println(Thread.currentThread().getName() + " say: Bye!");
}
}, "new thread");
System.out.println("main say: Starting new thread");
t.start();
System.out.println("main say: Waiting a little...");
Thread.sleep(1250);
System.out.println("main say: Interrupting new thread");
t.interrupt();
// p.shutdown();
System.out.println(String.format("main say: Executor state: isShutdown: %s, isTerminated: %s",
p.isShutdown(),
p.isTerminated()));
System.out.println("main say: Bye...");
}
Main question: why does ThreadPool interrupts its workers, when currentThread interrupted? Where can I learn about this its behavior?
And why in this example main thread don't exits, but do nothing? ThreadPool is inactive but not isTerminated and isShutdown and don't processing rest of tasks.

Main question: why does ThreadPool interrupts its workers, when currentThread interrupted? Where can I learn about this its behavior?
You are overgeneralizing. The invokeAll() methods of an ExecutorService cancel all unfinished tasks when they are interrupted. This is documented in the API docs.
If you're asking "how would I know it will do that" then the docs are your answer. If you're asking why the interface is designed that way, then it makes sense because when it is interrupted, the method throws InterruptedException instead of returning a value, and therefore it is reasonable to suppose that any further work that those unfinished tasks might perform would be wasted.
And why in this example main thread don't exits, but do nothing?
The "main thread" is the one that started at the beginning of main(). This thread does exit, and before it does so it does several other things, including creating, starting, and interrupting a Thread, and outputting several messages. It exits when control reaches the end of main().
But perhaps you mean thread "new thread" started directly by the main thread. This thread also does several things, including starting the monitor thread and submitting a job to the executor service. Or maybe you're asking why this thread does not exit while the ExecutorService is working on its job, but why would it exit while it's waiting for the invokeAll() method to return? Even though that method returns a list of Futures, its documentation is clear that it blocks until all the tasks submitted to it are complete, or an exception occurs.

Why the interrupts?
The interrupts to your tasks are mentioned in the API of ExecutorService.invokeAll():
Throws:
InterruptedException - if interrupted while waiting, in which case unfinished tasks are cancelled
So when the interrupt is received during your call to p.invokeAll(threads), all the tasks in threads are cancelled.
The API doesn't specify if Future.cancel() is called with mayInterruptIfRunning or not, but if you look in the code for AbstractExecutorService, from which ThreadPoolExecutor inherits its implementation of invokeAll(), you can see that the tasks are cancelled with interrupts enabled:
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
/* ... */
try {
/* ... */
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
I suppose this makes slightly more sense than cancelling them without interrupts, because there's already been an interrupt; this is "just propagating it".
Why doesn't the thread pool finish?
The program doesn't exit, and the thread pool is not shut down or terminated, because you simply never told it to shut it down.
So this is no different from the following reduced program:
public static void main(String[] args) throws Throwable {
final ExecutorService p = Executors.newFixedThreadPool(2);
p.execute(new Runnable() { public void run() { } });
Thread.sleep(1000);
System.out.println(String.format("main say: Executor state: isShutdown: %s, isTerminated: %s",
p.isShutdown(),
p.isTerminated()));
}
Thread pools don't have any special magic to guess when you meant to shut them down; they wait until you actually tell them to. The documentation for Executors.newFixedThreadPool() states:
The threads in the pool will exist until it is explicitly shutdown.
When you create thread pools, you need to ensure that they're eventually cleaned up. Usually this is by calling shutdown() or shutdownNow(). Why is this necessary? Because running threads are special in the context of Java garbage collection. Running threads are the starting points for determining what objects will not be garbage collected, and will never be garbage collected while they are still running. And a Java program never exits while there are still running threads (unless you call System.exit(), of course.)
There are some special situations where a thread pool might have no running threads, and thus be garbage collected. The API docs for ThreadPoolExecutor explains this:
Finalization
A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown(), then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting allowCoreThreadTimeOut(boolean).
So we can modify my example above to eventually exit like this:
final ThreadPoolExecutor p = new ThreadPoolExecutor(
0, 2, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
or this:
final ThreadPoolExecutor p = new ThreadPoolExecutor(
2, 2, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
p.allowCoreThreadTimeOut(true);
But it's often cleaner to call shutdown or shutdownNow when you're finished with your thread pool, instead of relying on a timeout.

Related

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.

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.

How can we save a thread for next task after its execution in java (Implementation of Thread pooling )

I need to ask about how thread pooling is implemented for having constant number of thread executing each time when there is task submission happened . (In Executor to avoid each time thread creation and deletion overhead)
executor.submit(Runnable)
Lets say we create some threads in the start and when task come we assign task to them(Thread) using any Queue impl . But after completing it s task how could a thread return to its pool again when as per the lifecycle of thread says that
"After execution of its run method it goes into TERMINATED state and can't be used again"
I am not understood how thread pool works for having constant number of threads for execution of any task to its queue .
It would be great if anyone could provide me an example of thread reuse after its completion of task .
!!Thanks in advance .!!
"After execution of its run method it goes into TERMINATED state and can't be used again"
It doesn't finish its run() Instead it has a loop which runs the run() of the tasks you provide it.
Simplifying the thread pool pattern dramatically you have code which looks like this.
final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
public void submit(Runnable runs) {
tasks.add(runs);
}
volatile boolean running = true;
// running in each thread in the pool
class RunsRunnable implement Runnable {
public void run() {
while(running) {
Runnable runs = tasks.take();
try {
runs.run();
} catch(Throwable t) {
// handles t
}
}
}
}
In this example, you can see that while the run() of each task completes, the run() of the thread itself does not until the pool is shutdown.
Usually what happens when we use thread pool , Its inside Run method it is forced to run iteratively. Until there are tasks available in the Queue.
in the below example pool.removeFromQueue() will run iteratively.
public class MyThread<V> extends Thread {
private MyThreadPool<V> pool;
private boolean active = true;
public boolean isActive() {
return active;
}
public void setPool(MyThreadPool<V> p) {
pool = p;
}
/**
* Checks if there are any unfinished tasks left. if there are , then runs
* the task and call back with output on resultListner Waits if there are no
* tasks available to run If shutDown is called on MyThreadPool, all waiting
* threads will exit and all running threads will exit after finishing the
* task
*/
#Override
public void run() {
ResultListener<V> result = pool.getResultListener();
Callable<V> task;
while (true) {
task = pool.removeFromQueue();
if (task != null) {
try {
V output = task.call();
result.finish(output);
} catch (Exception e) {
result.error(e);
}
} else {
if (!isActive())
break;
else {
synchronized (pool.getWaitLock()) {
try {
pool.getWaitLock().wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
void shutdown() {
active = false;
}
Need to design your thread pool
public MyThreadPool(int size, ResultListener<V> myResultListener) {
tasks = new LinkedList<Callable<V>>();
threads = new LinkedList<MyThread<V>>();
shutDown = false;
resultListener = myResultListener;
for (int i = 0; i < size; i++) {
MyThread<V> myThread = new MyThread<V>();
myThread.setPool(this);
threads.add(myThread);
myThread.start();
}
}
You can take a look here: http://www.ibm.com/developerworks/library/j-jtp0730/index.html for more details and an implementation example. The threads in the pool will wait if the queue is empty and will each start consome messages once they are notified that the queue has some elements.
ExecutorService executor = Executors.newFixedThreadPool(2);
- The above statement created a ThreadPool with fixed size of 2.
executor.execute(new Worker());
- The above statement takes an instance of the class Worker which has implemented Runnable Interface.
- Now here the Executors is an intermediate object, executing the task. Which manages the Thread Objects.
- By executing the above statement the run() method will be executed, and once the run() method completes, the thread doesNot go into dead state but moves back into the pool, waiting to have another work assigned to it, so it can once again move into Runnable state and then to running, all this is handled by Executors .
executor.shutdown();
- The above statement will shutdown the Executors itself, gracefully handling the shutdown of all the threads managed by it..shutdown() on that central object, which in turn could terminate each of the registered executors.
////////// Edited Part//////////////////////
- First of all Runnable has a run() method which canNot return anything, and run() method canNot throw a checked exception, So Callable was introduced in Java 5, which is of Parametric type , and has a method called call(), and it is capable of returning , and throwing Checked exceptions.
Now see this Example:
Thread t = new Thread(new Worker());
t.run();
t.start();
- t.run() is just a simple call to run() method, this won't span a thread of execution.
- t.start() whereas prepares for the things important for the initialization of the thread of execution, and then calls the run() method of the Runnable, and then assign the Task to the newly formed thread of execution, and returns quickly....
Threads in Java becomes a necessity when using Swing and AWT. Mainly the GUI component.
I am totally agree with Peter but want add steps related to ExecutorService execution flow, for clear understanding.
If you create pool (fixed size pool) of threads it does not means that threads were created.
If you submit and/or execute new Task (Runnuble or Callable) new thread will be created JUTS if count of created threads < size of pool
Created threads not returning to pool, threads can wait for new value in blocking queue, this point we can call RETURNING TO POOL
All threads from pool execs like Peter described above.

Timer: canceling running task

I need to create async thread that runs once with a delay of 2 minutes and that can be killed at any moment. I saw several possible solutions:
ScheduledExecutorService and FutureTask allow me to interrupt a running task, but I will have to invoke shutdown() to terminate all the running threads, and this will block user until the processes were terminated. Also, I will have to frequently invoke Thread.interrupted() as described in Enno Shioji's answer.
Timer and TimerTask do not require to release running threads, but I have no way to interrupt a running timer thread (Timer.cancel() just cancels future scheduling)
Using Thread and sleep with thread interruption problem.
Is there a good solution? (I'm using tomcat 7)
thank you
After some tests and researches, FutureTask.cancel() and Threads need similar handling of interrupts, as stated in Enno Shioji's answer
Check interruption flag in your logic
Act upon Interrupted exception
An example that tests interruption flag:
private final class MyTask implements Runnable {
public void run() {
try{
for(int j=0; j<100000000; j++) {
for(int i=1; i<1000000000; i++){
if(Thread.interrupted()){ //Don't use Thread.interrupt()!
Log.debug("Thread was interrupted for" + cache);
return; //Stop doing what you are doing and terminate.
}
Math.asin(0.1565365897770/i);
Math.tan(0.4567894289/i);
}
}
}catch(Throwable e){//if exception is uncaught, the scheduler may not run again
...
}
}
}
As I understand, ScheduledExecutorService maybe be shutdown when application ends running
For your scenario 2 with TimerTask, why not just return from the run() method after calling this.cancel()?
Here's a snippet from something I wrote. I use the same technique whenever the tool encounters a situation that would make further execution invalid, like a misconfiguration.
...
if ( count < 1 ) {
logger.error("CANCELING THREAD FOR " + host + ":" + jmxPort + "! " +
"- CONFIGURATION INCOMPLETE - DUMP_COUNT must be 1 or greater.");
this.cancel();
return;
}
...
Using Option 1 you can use FutureTask.cancel() with mayInterruptIfRunning parameter set to true to cancel your tasks.
The ScheduledExecutorService.scheduleAtFixedRate() creates a ScheduledFuture, which still can be canceled trough the FutureTask api.
Here is a naive test I've used to verify that task gets canceled. I suppose the worker thread may not be interrupted if you do some blocking IO (network or disk), but I haven't tested it. If cancel is called while task is not running, it all stops nicely, but if task is running when cancel is called the executor will try to kill the thread.
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
ScheduledFuture<?> future = executor.scheduleAtFixedRate(new Runnable() {
int i = 0;
public void run() {
int j = i++;
System.err.println("Run " + j);
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
System.err.println("Interrupted " + j);
}
}
}, 1000L, 2000L, TimeUnit.MILLISECONDS);
Thread.sleep(10000L);
System.err.println("Canceled " + future.cancel(true));
Thread.sleep(20000L);
executor.shutdownNow();
System.err.println("Finished");
}

Under what conditions will BlockingQueue.take throw interrupted exception?

Let us suppose that I have a thread that consumes items produced by another thread. Its run method is as follows, with inQueue being a BlockingQueue
boolean shutdown = false;
while (!shutdown) {
try {
WorkItem w = inQueue.take();
w.consume();
} catch (InterruptedException e) {
shutdown = true;
}
}
Furthermore, a different thread will signal that there are no more work items by interrupting this running thread. Will take() throw an interrupted exception if it does not need to block to retrieve the next work item. i.e. if the producer signals that it is done filling the work queue, is it possible to accidentally leave some items in inQueue or miss the interrupt?
A good way to signal termination of a blocking queue is to submit a 'poison' value into the queue that indicates a shutdown has occurred. This ensures that the expected behavior of the queue is honored. Calling Thread.interupt() is probably not a good idea if you care about clearing the queue.
To provide some code:
boolean shutdown = false;
while (!shutdown) {
try {
WorkItem w = inQueue.take();
if (w == QUEUE_IS_DEAD)
shutdown = true;
else
w.consume();
} catch (InterruptedException e) {
// possibly submit QUEUE_IS_DEAD to the queue
}
}
I wondered about the same thing and reading the javadoc for take() I believed that it would throw an interrupted exception only after having taken all the items in the queue, since if the queue had items, it would not have to "wait".
But I made a small test:
package se.fkykko.slask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
public class BlockingQueueTakeTest {
public static void main(String[] args) throws Exception {
Runner t = new Runner();
Thread t1 = new Thread(t);
for (int i = 0; i < 50; i++) {
t.queue.add(i);
}
System.out.println(("Number of items in queue: " + t.queue.size()));
t1.start();
Thread.sleep(1000);
t1.interrupt();
t1.join();
System.out.println(("Number of items in queue: " + t.queue.size()));
System.out.println(("Joined t1. Finished"));
}
private static final class Runner implements Runnable {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(100);
AtomicLong m_count = new AtomicLong(0);
#Override
public void run() {
try {
while (true) {
queue.take();
System.out.println("Took item " + m_count.incrementAndGet());
final long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start) < 100) {
Thread.yield(); //Spin wait
}
}
}
catch (InterruptedException ex) {
System.out.println("Interrupted. Count: " + m_count.get());
}
}
}
}
The runner will take 10-11 items and then finish i.e. take() will throw InterruptedException even if there still is items in the queue.
Summary: Use the Poison pill approach instead, then you have full control over how much is left in the queue.
According to javadoc, the take() method will throw InterruptedException if interrupted while waiting.
You can't in general interrupt the threads of an ExecutorService from external code if you used ExecutorService::execute(Runnable) to start the threads, because external code does not have a reference to the Thread objects of each of the running threads (see the end of this answer for a solution though, if you need ExecutorService::execute). However, if you instead use ExecutorService::submit(Callable<T>) to submit the jobs, you get back a Future<T>, which internally keeps a reference to the running thread once Callable::call() begins execution. This thread can be interrupted by calling Future::cancel(true). Any code within (or called by) the Callable that checks the current thread's interrupt status can therefore be interrupted via the Future reference. This includes BlockingQueue::take(), which, even when blocked, will respond to thread interruption. (JRE blocking methods will typically wake up if interrupted while blocked, realize they have been interrupted, and throw an InterruptedException.)
To summarize: Future::cancel() and Future::cancel(true) both cancel future work, while Future::cancel(true) also interrupts ongoing work (as long as the ongoing work responds to thread interrupt). Neither of the two cancel invocations affects work that has already successfully completed.
Note that once a thread is interrupted by cancellation, an InterruptException will be thrown within the thread (e.g. by BlockingQueue::take() in this case). However, you a CancellationException will be thrown back in the main thread the next time you call Future::get() on a successfully cancelled Future (i.e. a Future that was cancelled before it completed). This is different from what you would normally expect: if a non-cancelled Callable throws InterruptedException, the next call to Future::get() will throw InterruptedException, but if a cancelled Callable throws InterruptedException, the next call to Future::get() will through CancellationException.
Here's an example that illustrates this:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
public class Test {
public static void main(String[] args) throws Exception {
// Start Executor with 4 threads
int numThreads = 4;
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(numThreads);
try {
// Set up BlockingQueue for inputs, and List<Future> for outputs
BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
List<Future<String>> futures = new ArrayList<>(numThreads);
for (int i = 0; i < numThreads; i++) {
int threadIdx = i;
futures.add(executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
try {
// Get an input from the queue (blocking)
int val = queue.take();
return "Thread " + threadIdx + " got value " + val;
} catch (InterruptedException e) {
// Thrown once Future::cancel(true) is called
System.out.println("Thread " + threadIdx + " got interrupted");
// This value is returned to the Future, but can never
// be read, since the caller will get a CancellationException
return "Thread " + threadIdx + " got no value";
}
}
}));
}
// Enqueue (numThreads - 1) values into the queue, so that one thread blocks
for (int i = 0; i < numThreads - 1; i++) {
queue.add(100 + i);
}
// Cancel all futures
for (int i = 0; i < futures.size(); i++) {
Future<String> future = futures.get(i);
// Cancel the Future -- this doesn't throw an exception until
// the get() method is called
future.cancel(/* mayInterruptIfRunning = */ true);
try {
System.out.println(future.get());
} catch (CancellationException e) {
System.out.println("Future " + i + " was cancelled");
}
}
} finally {
// Terminate main after all threads have shut down (this call does not block,
// so main will exit before the threads stop running)
executor.shutdown();
}
}
}
Each time you run this, the output will be different, but here's one run:
Future 1 was cancelled
Future 0 was cancelled
Thread 2 got value 100
Thread 3 got value 101
Thread 1 got interrupted
This shows that Thread 2 and Thread 3 completed before Future::cancel() was called. Thread 1 was cancelled, so internally InterruptedException was thrown, and externally CancellationException was thrown. Thread 0 was cancelled before it started running. (Note that the thread indices won't in general correlate with the Future indices, so Future 0 was cancelled could correspond to either thread 0 or thread 1 being cancelled, and the same for Future 1 was cancelled.)
Advanced: one way to achieve the same effect with Executor::execute (which does not return a Future reference) rather than Executor::submit would be to create a ThreadPoolExecutor with a custom ThreadFactory, and have your ThreadFactory record a reference in a concurrent collection (e.g. a concurrent queue) for every thread created. Then to cancel all threads, you can simply call Thread::interrupt() on all previously-created threads. However, you will need to deal with the race condition that new threads may be created while you are interrupting existing threads. To handle this, set an AtomicBoolean flag, visible to the ThreadFactory, that tells it not to create any more threads, then once that is set, cancel the existing threads.
The java.concurrency.utils package was designed and implemented by some of the finest minds in concurrent programming. Also, interrupting threads as a means to terminate them is explicitly endorsed by their book "Java Concurrency in Practice". Therefore, I would be extremely surprised if any items were left in the queue due to an interrupt.

Categories

Resources