I'm having this odd behaviour. My program hangs eventhough I'm setting a time to force terminate it. could anyone point out what this strange behaviour could be?
here is my code where I start the threads
protected void pendingTaskStarter() throws Exception {
ExecutorService service = Executors.newFixedThreadPool(maxThreadNum);
ArrayList<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();
System.out.println("max thread num: " + maxThreadNum);
for(int i=0;i<maxThreadNum;i++){
Thread t = new PendingTaskConsumer();
Future<?> f=service.submit(t);
futures.add((Future<Runnable>) f);
}
for (Future<?> future:futures) {
future.get(5l,TimeUnit.MINUTES); // maximum thread's life is 5min (5l <-- 5 in long )
}
service.shutdownNow();
}
I am 100% sure that my program hangs somewhere in PendingTaskConsumer class based on the outputs within PendingTaskConsumer class.
Anyways codes in PendingTaskConsumer should be irrelevant as thread is supposedly forced to be terminated.
My question is in what scenraios the following line does not do as its expected.
future.get(5l,TimeUnit.MINUTES);
The program is running on Linux(Ubuntu) and using openjdk-7-jdk backage ( version 1.7)
As #GPI already stated in his/her answer, cancellation won't work properly, if your tasks do not repond to thread interruption via Thread.interrupt(). See Oracle: The Java™ Tutorials - Concurrency - Interrupts or Java Executors: how can I stop submitted tasks?.
But even if your tasks do not immediately stop if the thread is interrupted (=the interruption flag is set), you can timeout your method. Just don't listen to task completion by invoking every single get() method of your Futures! That's not necessary as you are not really interested in their result. Just shutdown your ExecutorService and wait for its termination.
protected void pendingTaskStarter() throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(maxThreadNum);
for (int i = 0; i < maxThreadNum; i++) {
service.submit(new PendingTaskConsumer());
}
// Shutdown service.
// This will continue to process already submitted tasks.
service.shutdown();
try {
// wait at least 5 minutes for the tasks to complete
if (!service.awaitTermination(5, TimeUnit.MINUTES)) {
// still not done yet -> force shutdown
// this will interrupt currently running tasks.
service.shutdownNow();
}
} catch (InterruptedException ex) {
// someone interrupted this thread. Shutdown tasks immediately
service.shutdownNow();
// propagate exception
throw ex;
}
}
So what happens here?
First, all tasks are submitted.
Then shutdown() is called on the ExecutorService. Note that the service will continue to execute already submitted tasks, but it will not accept new tasks.
Now, we wait for the service to terminate by calling awaitTermination with a timeout of 5 minutes. If this method returns true, which means, that the service has terminated within time, everything is fine and we're done. But if it returns false after 5 minutes, it means that the service is still running because there are some tasks that need more time to complete.
In that case, we shutdown the service immediately by calling shutdownNow(). Note that this method will not block! It just attempts to cancel all running tasks, usually by interrupting the threads that are currently executing them. This is exactly why your tasks should response to thread interruption properly! If they don't do this, interrupting the thread will have no effect at all!
No matter if shutdownNow was successful - we are done and do not wait any longer. So there might still be some tasks that are running because they don't react upon thread interruption (usually because a task is either not implemented properly or it is uninterruptibly on purpose). But we simply don't care.
Note the exception handler: When another thread interrupts the thread that is calling our method while it is waiting in method awaitTermination, an InterruptedException is thrown. We handle it by shutting down the service and re-throwing the exception! That is a good thing and makes our method a long-running-operation that is cancellable by itself!
Well... proper exception handling seems to be missing.
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* #param timeout the maximum time to wait
* #param unit the time unit of the timeout argument
* #return the computed result
* #throws CancellationException if the computation was cancelled
* #throws ExecutionException if the computation threw an
* exception
* #throws InterruptedException if the current thread was interrupted
* while waiting
* #throws **TimeoutException if the wait timed out**
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
If your call to future.get(5l,TimeUnit.MINUTES); expires, then an Exception is thrown and your service is never shut down.
So (one can assume) its internal threads are still running, at least the one that is executing your long running task). Seeing those are non-daemons thread (you'd have to custom the ThreadFactory of your executor for them to be), those pending threads prevent the JVM from shutting down.
If you wish to terminate the tasks forcibly, you can :
design your runnable task to respond to Thread.isInterrupted(), and exit when it sees that become true. (The practical effect of shutdownNow is to set the interrupted flag of your executor's thread )
If you can't (because your are blocked in some library's method that does not listen to interruption), then having a dameon thread seems like the only option.
But anyway, I'd put the executor's shutdown either earlier, or in a finally clause.
Related
From multiple articles around the internet it's advised not to swallow InterruptedException. It makes much more sense to do it with thread pool executors something like this when I'm going to reuse the same thread.
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(() -> {
printNumbers(); // first call
printNumbers(); // second call
});
Thread.sleep(3_000);
executor.shutdownNow(); // will interrupt the task
executor.awaitTermination(3, TimeUnit.SECONDS);
}
private static void printNumbers() {
for (int i = 0; i < 10; i++) {
System.out.print(i);
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // preserve interruption status
break;
}
}
}
Code sample above from DZone.
But in the case of creating new thread each time like:
Object LOCK = new Object();
public void doSomeJob() {
myThread = new Thread(new Runnable() {
public void run() {
try {
synchronized(LOCK) {
System.out.println("Inside run");
LOCK.wait();
}
} catch(InterruptedException ignored){}
}
}
}
Do I still need to call Thread.currentThread().interrupt();? Will that make any sense?
Good references:
https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/
http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html
I will give an answer based on section 7.1.2 of great book Concurrency in Practice by Brian Goetz.
In your first example you use ExecutorService. ExecutorService manages it's own threads. You are not the owner of those Threads so you do not know what interruption means to them ( for example ThreadPool might choose to kill Threads that were interrupted and create new ones). That is why you should preserve interruption status when you submit a cancelable task to this pool. This citation applies to this case:
Tasks do not execute in threads they own.They borrow threads owned by a service such as a thread pool. Code that
doesn't own the thread (for a thread pool, any code outside of the thread pool implementation) should be careful to
preserve the interrupted status so that the owning code can eventually act on it, even if the "guest" code acts on the
interruption as well. (If you are housesitting for someone, you don't throw out the mail that comes while they're away - you save it and let them deal with it when they get back, even if you do read their magazines.)
In the second case you manage an instance of Thread manually. So you are the owner of it. Therfore you decide what interruption means to this Thread and you do not have to preserve the Interruption Status in the second case if you do not want to apply any Thread Interruption Policy for it :
What you should not do is swallow the InterruptedException by catching it and doing nothing in the catch block, unless your code is actually implementing the interruption policy for a thread
Note also that Thread Interruption Policy is different than Task Cancellation Policy :
Thread Interruption Policy - defines how Thread reacts to interruption (for example ThreadPool might kill Thread that was interrupted and create a new one). It is defined by the owner of the thread.
Task Cancellation Policy - defines how task reacts to cancellation. Cancellation is usually implemented with interruption. The one who implements the task chooses if task in responsive to interruption. This is easily achieved if your task calls methods that throw InterruptedException. Or you can check the interruption flag of the Thread by calling Thread::isInterrupted (for example in a loop). The implementor of the task chooses how to handle this.
Also you should not take any assumptions of Thread Interruption Policy (if you are not the owner of the Thread). That is why preserving Interruption Status or rethrowing InterruptedException is considered a good practice.
If your lock comes from java.util.concurrent.locks.Lock and is interruptible (using .lockInterruptibly()), it does make sense to interrupt the process so everything might be interrupted and cancelled.
Read chapter Implementation Considerations from the documentation.
But if your lock is non-interruptible (using .lock()) it will not make sense as you won't be able to interrupt the lock.
In your case, you're using wait() which is interruptable as written here, and will throw an InterruptedException.
The explanations in DZone link https://dzone.com/articles/understanding-thread-interruption-in-java in your question are very detailed. Thread.currentThread().interrupt(); raises back interrupted exception status which is cleared before by blocking methods (sleep). It is done to ensure second loop interrupted too (it will catch the exception as it is on the same thread).
Before I finish, I wanted to emphasize on an important detail about
what happens to a thread’s interruption status when a blocking code
responds to interruption by throwing InterruptedException. I had left
out the detail till now to avoid confusion.
Before a blocking code throws an InterruptedException, it marks the
interruption status as false. Thus, when handling of the
InterruptedException is done, you should also preserve the
interruption status by callingThread.currentThread().interrupt().
Let’s see how this information applies to the example below. In the
task that is submitted to the ExecutorService, the printNumbers()
method is called twice. When the task is interrupted by a call
toshutdownNow(), the first call to the method finishes early and then
the execution reaches the second call. The interruption is called by
the main thread only once. The interruption is communicated to the
second execution of the printNumber() method by the call to
Thread.currentThread().interrupt() during the first execution. Hence
the second execution also finishes early just after printing the first
number. Not preserving the interruption status would have caused the
second execution of the method to run fully for 9 seconds.
Where to use Thread.currentThread().interrupt(); depends on your code, second example is not complete to understand the need for it.
I have a future that does some intensive task. I call that future with a timeout. If it times out, I throw an exception back to client as well as create another scheduledfuture to cancel first future eventually after a while. The idea is to give sometime after initial timeout for future to complete its task, but if it doesn't complete in that time, just kill it.
My code looks like
try {
return future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException) {
//create a scheduledfuture here which waits for another 5s
// and kill the above future is it is still not done
//the callable of scheduledfuture looks like -
/*
if (!future.isDone()) {
future.cancel(true);
}
*/
}
Now two questions here -
1. The future.cancel(true) will just set the interrupt flag to true. It will not end the task as it is. How should I end the task? Is there a JVM process internally that checks threads for interrupted flag and terminates them if true?
2. As the interrupted flag is now set, after the task completes, is there a process that resets the flag? Else that thread managed through ExecutorService will fail with InterruptedException when it tries to take up next request which contains a blocking call.
How should I end the task?
Run the task is a separate process and kill the process to stop it. There is no safe way to stop a thread in Java, unless the task has been coded to support it.
As the interrupted flag is now set after the task completes, is there a process that resets the flag?
Yes, the ExecutorService resets the interrupted flag.
I have an ExecutorService that runs a few threads.
What I am trying to accomplish is to execute, and then wait for all threads to terminate. To give you more background, every thread1 connects to a website.
This is what I came up with:
public static void terminateExecutor(ExecutorService taskExecutor) {
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Some tasks were interrupted!"); //This gets printed
}
}
Now, strangely enough, the main thread that uses the ExecutorService terminates, but the thread1s in it don't.
I noticed this because thread1 threw an error (the main thread at this point was already dead) telling me that it didn't find the URL specified (so I guess it's something related to connections).
Is it possible that awaitTermination doesn't terminate the thread1 because its trying (and retrying it seems) to connect to an invalid link?
I cannot stop the thread1 in any other way (or at least to my knowledge I can't), because there isn't any kind of loop.
EDIT:
I get thread1 by creating a new class and feeding it to the executor.
for (....)
{
String urlToVisit = globalUrl + links.get(i);
Thread thread1 = new MagicalThread(urlToVisit, 2).getThread();
executor.execute(thread1);
}
terminateExecutor(executor.getExecutor());
From the Javadoc (emphasis mine):
Blocks until all tasks have completed execution after a shutdown request
You need to call shutdown() before calling awaitTermination, otherwise it does nothing meaningful.
The executor uses interruption to let the threads know it's time to quit. If your tasks are using blocking I/O then they will be blocked and can't check the interrupt flag. There is no ability for the blocked task to respond to the interruption in the way that happens with sleep or wait, where interruption causes the threads to wake up and throw an InterruptedException.
If you set a timeout on the socket then, once the socket times out, the task can check for interruption. Also you can have the task respond to interrupt by closing the socket. See https://www.javaspecialists.eu/archive/Issue056.html
Be aware that implementing this in a threadpool is more involved than in the example given in the linked article. Nothing about the executor lets the pool call methods on a task besides run. One way to do it would be to put a reference to the socket in a ThreadLocal. Then you could make a ThreadFactory for the pool to use to subclass Thread with a method that overrides the interrupt method on the thread to get the socket from the ThreadLocal and close it.
When
taskExecutor.awaitTermination(2, TimeUnit.SECONDS);
returns, it doesn't guarantee that the ExecutorService has terminated. Look at its return value:
[Returns] true if this executor terminated and false if the timeout elapsed before termination
You don't check this value, but I'll bet it's returning false if the thing you're running in the ExecutorService is still running.
I am using an ExecutorService with a fixedThreadPool. I create threads by implementing the Runnable interface. In the run() method, I am calling a time consuming function (let's say Thread.sleep() for now) and finally add an element to a thread safe CopyOnWriteArrayList. I am submitting threads in a for-loop. At the end of the for-loop I shutdown the ExecutorService and await termination.
However, the number of elements in the list does not turn out to be the same as the number of loop-iterations. Where is my mistake in concurrency thinking?
Here is a code example for this problem:
public class TestProgram {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(4);
CopyOnWriteArrayList<String> stringList = new CopyOnWriteArrayList<String>();
for (int i = 0; i < 1000; i++) {
executor.submit(new myThread(stringList));
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
System.out.println(Integer.toString(stringList.size()));
}
}
class myThread implements Runnable {
CopyOnWriteArrayList<String> stringList;
public myThread(CopyOnWriteArrayList<String> stringList) {
this.stringList = stringList;
}
public void run() {
String string = new String("test");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(myThread.class.getName()).log(Level.SEVERE, null, ex);
}
stringList.add(string);
}
}
You're just not giving it enough time to complete. If you want to execute this serially you would need 1000 * 100 milliseconds, which is 100 seconds. You are running it with four threads, so divide that by 4 and you get 25 seconds. You only wait 10 seconds to complete. Increase that to 26 seconds just to be safe and you should see your result.
The ExecutorService#awaitTermination will wait the N number of seconds to complete, if it doesn't complete it will simply return out and continue the execution. To prove my point check the return value
System.out.println(executor.awaitTermination(10, TimeUnit.SECONDS));
The better solution here, is to use a new CountDownLatch(1000), have each Runnable task countDown after it adds to the list and finally have the main thread await completion.
The documentation of ExecutorService.shutdown says the following:
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
This method does not wait for previously submitted tasks to complete
execution. Use awaitTermination to do that.
This means that you indicate your ExecutorService that it must stop it's services. Thus, this method sets a flag which indicates that the ExecutorService will end soon, which allows the main thread to returns from this method without problems.
ExecutorService.awaitTermination, moreover, reads as follows:
Blocks until all tasks have completed execution after a shutdown
request, or the timeout occurs, or the current thread is interrupted,
whichever happens first.
This means that the main thread will be blocked inside the method, where it will only be returned when the tasks sent to ExecutorService finish. In both cases, the developer intends to end the ExecutorService function. But with awaitTermination, the developer is saying ExecutorService should be terminated regardless of their tasks have been carried out or not.
As each task takes at least 100 milliseconds to complete, no one will possibly be completed because ExecutorService has a tolerance of only 10 milliseconds for completion of all it's tasks.
There is no point in calling shutdown and awaitTermination at the same time (or preceded by another). According to your code, shutdown has no effect. If you want your tasks to become completed, and that ExecutorService is terminated without caring if your main thread will continue, just use shutdown. If you do not want your main thread to be blocked, and simply want to end with ExecutorService, use shutdownNow.
If, on the other hand, you want your main thread to wait for the execution of your tasks without a certain time to be specified, you may have to use Java Synchronizers. Some of Java Synchronizers are as follow:
Latches
FutureTasks
Semaphores
Barriers
For your case, I believe you can use CountDownLatch. Make a new CountDownLatch object have the number of tasks running on your ExecutorService. As they are completed, the count is decreased, and so, your main thread can expect completion and continue after all.
I hope you have understood and you can do what you want. If you have further questions, the documentation of CountDownLatch demonstrates perfectly how you can synchronize tasks. Good luck.
In that code snippet one issue will be there.
executor.awaitTermination(10, TimeUnit.SECONDS);
Here it will wait for 10 seconds after that it will break.
You will try following snippet.
while (true) {
if(executor.awaitTermination(10, TimeUnit.SECONDS))
break;
}
I am using an ExecutorService for a connection task as below:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions));
connection = future.get(300000, TimeUnit.SECONDS);
executor.shutdownNow();
The call() method calls a .connect() method (proprietary API). This connect method spawns various threadpools etc. My concern is that if the future times out and kills the executor, will the threads that may have already spawned by calling the .connect() method in the future also end? I know that killing a thread will also kill any child threads but does this follow the same logic?
You are right in your assumption, if the Future times out, some hanging threads will remain. Even worse, shutdownNow() will not even shutdown your pool thread (not to mention proprietary API threads). It merely stops accepting new jobs. ExecutorService thread pool will terminate all threads once all running tasks finish.
What you can do is to try canceling the future and interrupting it. First handle InterruptedException inside your future:
class ConnectThread implements Callbale<ApplicationConnection> {
public ApplicationConnection call() {
try {
return prioprietaryApi.connect();
} catch(InterruptedException e) {
prioprietaryApi.cleanUp();
throw e;
}
}
}
Now simply run:
future.cancel(true);
However your proprietary API might not handle InterruptedException (it will not rethrow it from connect(), moreover you might not have access to any cleanUp() method.
In these circumstances just... forget about it. That Future will eventually terminate and clean up after itself, ignoring the fact that you no longer wait for it. Of course this might lead to various scalability issues.
BTW if the only thing you want to achieve is limiting the maximum time given method runs, consider TimeLimiter from guava.
As per javadoc
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution. There are no guarantees beyond best-effort attempts to stop
processing actively executing tasks. For example, typical
implementations will cancel via Thread.interrupt(), so any task that
fails to respond to interrupts may never terminate.