I want to manage a list of Futures objects returned by my TaskExecutor.
I've something like this
List<Future<String>> list
void process(ProcessThis processThis) {
for ( ...) {
Future<String> future = taskExecutor.submit(processThis);
list.add(future)
}
}
void removeFutures() {
for(Future future : list) {
assert future.cancel(true);
}
ProcessThis is a task that implements Callable< String> and checks for Thread.interrupted() status
public String call() {
while (true) {
if (Thread.interrupted()) {
break;
}
doSomething();
}
}
Now the problem is that only a subset of the concurrent Threads is returning 'true' when Thread.interrupted() is called.
The assert in removeFutures() returns true for every future that is removed (I checked isDone() and isCompleted() as well.
The number of Threads that are interrupted is random. Over 15 running Threads sometimes 13 are interrupted, sometimes 2 ...
I really don't understand where's the issue. if I call future.cancel(true) and this returns true... and then I check Thread.interrupted (this is called only once), I expect this to return true as well.
Any idea of what am I missing?
I'm on build java 1.6.0_02-b05
Be aware that Thread.interrupted() returns the current interrupted status and then clears it, so all future invocations will return false. What you want is probably Thread.currentThread().isInterrupted().
Also be aware that future.cancel(true) will usually only return false if the task had already been completed or canceled. If it returns true, that is no guarantee that the task will actually be canceled.
What is happening in doSomething()? Its possible that a RuntimeException is escaping somewhere due to the interrupt. Do you have an UncaughtExceptionHandler set? If not, you'll need to pass a ThreadFactory to the Executor that will set the exception handler and log any missed exceptions.
At least, you should restore the interruption flag to make taskExecutor aware of the thread interruption:
public String call() {
while (true) {
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
break;
}
doSomething();
}
}
A potential problem that interrupts are often swallowed. So somewhere deep in doSomething() (or even in class loading), an interrupt may be caught by, say, wait() and then discarded by 'careless' code. Interrupts are evil, IMO.
It may be worth checking that all of you tasks are actually running at the time of the cancel.
Related
I am writing a program where i invoke multiple threads from my main function. There is a For loop which starts threads in a loop.
I want to implement a functionality where if some exception occurs in one thread then it should stop all the currently running/submitted threads, or the threads in waiting state. And also no more further threads should be submitted from the loop.
P.S. I am maintaining a Map which keeps record of all threads Map <threadName, Thread>
And i am not using executor service.
How to kill or stop all threads and prevent further threads from being submitted after some exception occurs in any one thread.
You can't forcefully stop a thread in Java.
Yes, there are methods like Thread.stop() and related, but they've been deprecated for years for good reason.
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
Because of the above, you shouldn't use those methods, nor rely on them working (many APIs with thread-heavy methods will happily ignore any calls to stop() and interrupt()).
Once we got that out of the way, you can still implement logic for your threads to terminate ASAP when you ask them to, in an elegant manner.
You need to do two things:
1.- Check for Thread.interrupted() inside your run() method. Something like this:
#Override
public synchronized void run() {
while (yourFinishCondition && !Thread.interrupted()) {
// do stuff until you finish, or until the thread is interrupted from the outside
}
}
2.- Invoke interrupt() on every thread from your main method to signal them for termination when you need to, like this:
Thread.UncaughtExceptionHandler h = (thread, exception) -> {
thread0.interrupt();
thread1.interrupt();
thread2.interrupt();
};
A little PoC:
public class Main {
static class MyThread extends Thread {
public MyThread(String s) {
super(s);
}
#Override
public synchronized void run() {
while(!Thread.interrupted()) {
if (new Random().nextInt(1000000) == 7) {
throw new RuntimeException(Thread.currentThread().getName()+" oops!");
}
}
System.out.println(Thread.currentThread().getName()+" interrupted");
}
}
public static void main(String[] args) {
final MyThread thread0 = new MyThread("thread0");
final MyThread thread1 = new MyThread("thread1");
final MyThread thread2 = new MyThread("thread2");
Thread.UncaughtExceptionHandler h = (thread, exception) -> {
System.out.println(exception.getMessage());
thread0.interrupt();
thread1.interrupt();
thread2.interrupt();
};
thread0.setUncaughtExceptionHandler(h);
thread1.setUncaughtExceptionHandler(h);
thread2.setUncaughtExceptionHandler(h);
thread0.start();
thread1.start();
thread2.start();
}
}
Output:
thread2 oops!
thread1 interrupted
thread0 interrupted
Further reading: https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop()+to+terminate+threads
Note that there is no "built in" functionality to stop a thread in java - some methods do exist but all are deprecated since they might cause trouble if the running code is not cooperative. So your code must implement some method to exit the run()-method based on some flag and this must be set from outside the thread. If your threads are using wait() a lot a call to interrupt() might come in handy.
You could write the code to kill all the running threads in finally block or catch block(which might not be recommended)
On killing all the running threads,refer this thread
If I got you question correct, You need to catch the exception and need to keep/maintain the list as a shared object, then call thread.stop() on the other threads will solve the problem right? But the stop method is deprecated in recent versions of java, So you can use thread.yield() to make the thread release the CPU and other resources, But still it will not guarantee the immediate termination of threads.
This question already has answers here:
How to stop a java thread gracefully?
(6 answers)
Closed 8 years ago.
As i have Written a Simple Java Program to call Thread . below is my code
public class ThreadPoolForParallelExec {
public static void main(String args[]) {
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
service.submit(new Task(i));
}
service.shutdown();
}
}
final class Task implements Runnable {
private int taskId;
public Task(int id) {
this.taskId = id;
}
#Override
public void run() {
myclient.intializeAndConnectRemoteMachine(taskId);
Thread.currentThread().stop();
Thread.currentThread().isInterrupted();
}
}
However , I need to terminate the Executor or Thread . I tried Thread.currentThread().stop(); and
Thread.currentThread().stop(); both didnt work :( could you please suggets .
Generally speaking, to kill thread is a bad idea, and in fact, the latest Java specification deprecate that.
Instead, try to finish the thread gracefully within the thread itself. That is the consistent structure.
Just let the method end normally.
Then the Thread will be idle and the ExecutorService will shutdown afterwards.
I think you should call to interrupt() and then wait Threads to finish. Then you could do any actions without having threads running.
you can either use Thread.interrupt() or use volatile flag in run method and set it false when you want to stop thread.
#Override
public void run() {
while (running) {
try {
....
} catch (InterruptedException e) {
running = false;
}
}
}
while running is flag initialized as true.
for more details you can refer this link
The documentation for version 1.5 says:
interrupt
public void interrupt()
Interrupts this thread.
Unless the current thread is interrupting itself, which
is always permitted, the checkAccess method of this thread
is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the
wait(), wait(long), or wait(long, int) methods of the
Object class, or of the join(), join(long), join(long,
int), sleep(long), or sleep(long, int), methods of this
class, then its interrupt status will be cleared and it
will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an
interruptible channel then the channel will be closed,
the thread's interrupt status will be set, and the
thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the
thread's interrupt status will be set and it will
return immediately from the selection operation,
possibly with a non-zero value, just as if the
selector's wakeup method were invoked.
If none of the previous conditions hold then this
thread's interrupt status will be set.
Throws:
SecurityException - if the current thread cannot modify this thread
Never use Thread.stop. It has been deprecated:
From JLS:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it.
Make sure you had made the guarding boolean field volatile to make sure the reading thread sees changes from the writing thread.
I try to execute several tasks in parallel with a CompletionService. The problems arise, when i try to implement cancelation.
Here is a sketch of the code I use:
void startTasks(int numberOfTasks) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
CompletionService<TaskResultType> completionService = new ExecutorCompletionService<TaskResultType>(executor);
ConcurrentLinkedQueue<TaskResultType> results = new ConcurrentLinkedQueue<BenchmarkResult>();
ArrayList<Future> futures = new ArrayList<Future>();
for (int i = 0; i < numberOfTasks ; i++) {
TypeOfTask task = ... ;
Future future = completionService.submit(task);
futures.add(future);
}
boolean failed = false;
Throwable cause = null;
for (int i = 0; i < numberOfThreads; i++) {
try {
Future<TaskResultType> resultFuture = completionService.take();
TaskResultType result = resultFuture.get();
results.add(result);
} catch (ExecutionException e) {
failed = true;
cause = e.getCause();
/* cancel all other running tasks in case of failure in one task */
for (Future future : futures) {
future.cancel(true);
}
} catch (CancellationException e) {
// consume (planned cancellation from calling future.cancel())
}
}
executor.shutdown();
// code to throw an exception using cause
}
The tasks implement Callable.
When I now throw an exception in one of the tasks in most of the cases it works out fine, i.e. I immediately get the CancellationExceptions from the other tasks and the tasks finish immediately (lets call this case A). But sometimes (lets call this case B), some of the tasks finish first and then throw the CancellationException. Future.cancel(true) returned true in both cases for all tasks (except the one with the initial ExecutionException, because this one was already canceled).
I check for the interrupted flag with Thread.currentThread.isInterrupted(), in the tasks that do complete (i.e. the tasks where the cancelation is unsuccessful), the interrupted flag is set to false.
All that seems to be very strange behavior in my eyes. Anybody any idea what the problem could be?
Update
The best idea so far I have is, that somewhere deep within the code comprising the task (only some high level code is from myself) the interrupted status is consumed, e.g. by a catched InterruptedException which doesn't call Thread.interrupt() to reestablish the status. The exact time the interrupted flag is set by Future.cancel() might vary slightly due to scheduling of the threads, that would explain the inconsistent behavior. Would a consumed interrupted status explain the behavior of case B?
But sometimes, some of the tasks finish first and then throw the
CancellationException.
Could it be the case that you cancel a task, it's normally interrupted (in this state you may think that it returns a result, but for the CompletionService it's cancelled), the future is being returned by take(), you call future.get() and there is the CancellationException.
You could also have a look at Guava's Futures.allAsList, which seems to be doing a very similar thing:
Creates a new ListenableFuture whose value is a list containing the values of all its input futures, if all succeed. If any input fails, the returned future fails.
But sometimes, some of the tasks finish first and then throw the CancellationException. Future.cancel(true) returned true in both cases for all tasks (except the one with the initial ExecutionException, because this one was already canceled).
If your program was not finishing (or taking a long time to finish after an exception is thrown) then I suspect your problem is that one of the tasks is doing IO or otherwise blocked and is not checking for Thread.currentThread().isInterrupted(). So even though you have canceled the Future and the thread is interrupted, this doesn't get detected.
However, it seems like the program is finishing. So I'm not sure what the error case is here. If you catch an exception you call future.cancel(true) on all of the futures in the list. The one that threw and the ones that have already finished should all return false since they can't be canceled. The ones that returned true from cancel should have been interrupted.
For example. if the 2nd to last thread throws an exception then future.cancel(true) should only return true for the last thread running.
One thing to do is to remove the futures as they finish so you don't re-cancel already completed jobs. But all that might do is mask the issue you are seeing now:
Future<TaskResultType> resultFuture = completionService.take();
futures.remove(resultFuture);
Update:
It is highly possible that some code is swallowing the interrupt. It happens all of the time unfortunately. If some of the threads are not finishing immediately when they are canceled and are running to completion then this is probably what is happening.
I push my Futures from a ExecutorService into a hash map. Later, I may call cancel on Futures from within the hash map. Although the result is true, I later hit breakpoints within the Callable procedure, as if the Future cancel() had no effect. I think it might be a case of two different references here (even though the reference IDs are listed as the same when breakpointing), but was wondering if some experts could chime in. Here's what the code looks like:
ExecutorService taskExecutor = Executors.newCachedThreadPool();
Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();
Future<Object> future = taskExecutor.submit(new MyProcessor(uid));
results.put(uid, future);
I allow processing to continue (it's a loop that submits tasks as they are passed in), and later I may attempt to cancel from an outside source by calling this method:
public static synchronized boolean cancelThread(String uid) {
Future<Object> future = results.get(uid);
boolean success = false;
if (future != null) {
success = (future.isDone() ? true : future.cancel(true));
if (success)
results.remove(uid);
}
return success;
}
But I still encounter a "non-cancelled" path within MyProcessor.call() after future.cancel() is called - i.e. it's not really being cancelled.
Where am I going wrong with this? Is there a better was to do this?
I later hit breakpoints within the Callable procedure, as if the Future cancel() had no effect.
Future.cancel(true) removes a job that is in the queue and not yet running but if the job is already running it does the equivalent of Thread.interrupt() on the thread running the job. This sets the interrupt bit on the thread and causes any sleep(), wait(), and some other methods to throw InterruptedException.
It is important to realize that it does not stop the thread. You need to actively check for the interrupt flag in your thread loop or properly handle InterruptedException.
See my SO answer here for more details: How to suspend thread using thread's id?
FutureTask :: boolean cancel(boolean mayInterruptIfRunning) will perform interrupt on current running thread.
FutureTask.java
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt(); ////////////HERE/////////////
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
JavaDoc says the below for interrupt
public void interrupt()
Interrupts this thread. Unless the current
thread is interrupting itself, which is always permitted, the
checkAccess method of this thread is invoked, which may cause a
SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long),
or wait(long, int) methods of the Object class, or of the join(),
join(long), join(long, int), sleep(long), or sleep(long, int), methods
of this class, then its interrupt status will be cleared and it will
receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible
channel then the channel will be closed, the thread's interrupt status
will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt
status will be set and it will return immediately from the selection
operation, possibly with a non-zero value, just as if the selector's
wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt
status will be set.
Interrupting a thread that is not alive need not have any effect.
Throws: SecurityException - if the current thread cannot modify this
thread
To conclude; cancel of FutureTask has only impact if the thread is blocked (in an invocation of the wait(),...) else it is developer responsibility to check Thread.currentThread().isInterrupted() to quit; while performing non blocked operation.
I have a situation where I have 2 blocking queues. The first I insert some tasks that I execute. When each task completes, it adds a task to the second queue, where they are executed.
So my first queue is easy: I just check to make sure it's not empty and execute, else I interrupt():
public void run() {
try {
if (taskQueue1.isEmpty()) {
SomeTask task = taskQueue1.poll();
doTask(task);
taskQueue2.add(task);
}
else {
Thread.currentThread().interrupt();
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
The second one I do the following, which as you can tell, doesn't work:
public void run() {
try {
SomeTask2 task2 = taskQueue2.take();
doTask(task2);
}
catch (InterruptedException ex) {
}
Thread.currentThread().interrupt();
}
How would you solve it so that the second BlockingQueue doesn't block on take(), yet finishes only when it knows there are no more items to be added. It would be good if the 2nd thread could see the 1st blocking queue perhaps, and check if that was empty and the 2nd queue was also empty, then it would interrupt.
I could also use a Poison object, but would prefer something else.
NB: This isn't the exact code, just something I wrote here:
You make it sound as though the thread processing the first queue knows that there are no more tasks coming as soon as its queue is drained. That sounds suspicious, but I'll take you at your word and propose a solution anyway.
Define an AtomicInteger visible to both threads. Initialize it to positive one.
Define the first thread's operation as follows:
Loop on Queue#poll().
If Queue#poll() returns null, call AtomicInteger#decrementAndGet() on the shared integer.
If AtomicInteger#decrementAndGet() returned zero, interrupt the second thread via Thread#interrupt(). (This handles the case where no items ever arrived.)
In either case, exit the loop.
Otherwise, process the extracted item, call AtomicInteger#incrementAndGet() on the shared integer, add the extracted item to the second thread's queue, and continue the loop.
Define the second thread's operation as follows:
Loop blocking on BlockingQueue#take().
If BlockingQueue#take() throws InterruptedException, catch the exception, call Thread.currentThread().interrupt(), and exit the loop.
Otherwise, process the extracted item.
Call AtomicInteger#decrementAndGet() on the shared integer.
If AtomicInteger#decrementAndGet() returned zero, exit the loop.
Otherwise, continue the loop.
Make sure you understand the idea before trying to write the actual code. The contract is that the second thread continues waiting on more items from its queue until the count of expected tasks reaches zero. At that point, the producing thread (the first one) will no longer push any new items into the second thread's queue, so the second thread knows that it's safe to stop servicing its queue.
The screwy case arises when no tasks ever arrive at the first thread's queue. Since the second thread only decrements and tests the count after it processes an item, if it never gets a chance to process any items, it won't ever consider stopping. We use thread interruption to handle that case, at the cost of another conditional branch in the first thread's loop termination steps. Fortunately, that branch will execute only once.
There are many designs that could work here. I merely described one that introduced only one additional entity—the shared atomic integer—but even then, it's fiddly. I think that using a poison pill would be much cleaner, though I do concede that neither Queue#add() nor BlockingQueue#put() accept null as a valid element (due to Queue#poll()'s return value contract). It would be otherwise be easy to use null as a poison pill.
I can't figure out what you are actually trying to do here, but I can say that the interrupt() in your first run() method is either pointless or wrong.
If you are running the run() method in your own Thread object, then that thread is about to exit anyway, so there's no point interrupting it.
If you are running the run() method in an executor with a thread pool, then you most likely don't want to kill the thread or shut down the executor at all ... at that point. And if you do want to shutdown the executor, then you should call one of its shutdown methods.
For instance, here's a version what does what you seeming to be doing without all of the interrupt stuff, and without thread creation/destruction churn.
public class TaskExecutor {
private ExecutorService executor = new ThreadPoolExecutorService(...);
public void submitTask1(final SomeTask task) {
executor.submit(new Runnable(){
public void run() {
doTask(task);
submitTask2(task);
}
});
}
public void submitTask2(final SomeTask task) {
executor.submit(new Runnable(){
public void run() {
doTask2(task);
}
});
}
public void shutdown() {
executor.shutdown();
}
}
If you want separate queuing for the tasks, simply create and use two different executors.