FutureTask cancel() - java

Basically I have the following snippet,
(let [task (FutureTask. fn)
thr (Thread. task)]
(.start thr)
;;wait for signal...
(.cancel task true)
(.stop thr))
Problem is once in a while cancel does not work, AFAICT cancel causes and exception to be thrown but some piece of code down the line catches it? Is there a sure way to cancel a future task?
fn is a function that basically does a series of long running calculations so I can't loop checking for a boolean flag.

There is no way to stop a running task automatically in Java - in the general case it is not safe to simply "kill" an executing thread, as doing so could leave things in an inconsistent state. As a result, this ability was intentionally left out Java.
When you cancel a task, a flag is set in the executing thread, but no exception is thrown. In order to allow a task to be cancelled, you will have to write code to periodically check if the thread has been interrupted:
while (notDone) {
if (Thread.isInterrupted()){
return; // we were cancelled (or interrupted in some other way)
}
doSomeHardWork()
}

According to my (limited) knowledge, there is no general method to do that. It's because you could have one uninterruptible, remote task, you could have one task which is pure function and thus safe to kill, you could have many subtasks (as nerdytenor mentioned -- check for isInterrupted state between each), you could have mix of everything, you could have task that when killed would put other tasks in global lock state... So as far as I know you have to do it yourself.
What kind of calculations do you perform? Can you do anything inside? Maybe create some global, thread-safe table toInterrupt and check in each subtask if the whole task is about to be cancelled? I know this is very non-idiomatic but can't think of anything better for now.
Or if those are really pure-functional calculations and you are really certain about that -- kill process/thread and hope you were right.

This question probably is related Executing a function with a timeout
The macro works for my code, the thunk-timeout code is here
(defmacro with-timeout [time & body]
`(thunk-timeout (fn [] ~#body) ~time))

Related

How to terminate(or abort) a timetask immediately

I want to terminate(or abort) a task immediately when it is running, not to wait its ending. I search in JDK, the Timer class and the TimerTask class not satisfied, their cancel method is not proper for me, for the task will contiue to execute util it finish, but I want to stop it immediately.
What should I do? I serach for Spring and Quartz, but no good idea...
This is not something that is recommended to do in a multi threaded environment as it can break your code in all sorts of ways. For example imagine you are half way through changing something and suddenly your thread gets killed leaving it in a half-modified state. Because it is not recommended no easy way is provided to do it.
The correct way to do this is to use a Thread and interrupt it.
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Inside your Thread code you can check isInterrupted() at times where it would be appropriate to abort and abort, but the abort is controlled by the running thread which is the only thing that knows when it is safe to do so.
The ScheduledExecutorService also allows you to work with a ScheduledFuture and cancel that, which then works in the same way as interrupting the thread does.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)

Android stop a thread that is executing a single library function

I have an application which uses a separate thread to execute a calculation performed in code from a separate library. I would like the user to able to cancel this operation as, depending on the parameters, it can take a long time.
I cannot use a stopping variable or check for interrupts as the calculation from the applications point of view is a single line
public void run() {
result = library.performCalculation(params);
}
I would like to be able to use thread.stop() but as far as I'm aware this is not posible on android.
Is there anyway I can cause the thread to stop running?
You're correct, Thread.stop() is not available on Android (and even on systems where it is still supported, its problems outweight its usefulness).
What you can do is two-fold. First, call thread.interrupt() to set an interrupted flag on the thread running your library. Second, modify your library at appropriate point(s) to call isInterrupted() to determine if it is interrupted and, if so, it should voluntarily clean up and leave.
An AsyncTask can be Cancelled. Put that into an AsyncTask and call
AsyncTask.cancel(true);

Java interrupts

I'm trying to implement a sort of interrupt process into my java program so that if an operation takes longer than 5 minutes, i can kill it.
Is there any sort of generic way I can do this? I'm using an external API to carry out very processor intensive calculations and it already multithreads the process so can I still use the executor class to do this?
-edit-
Ended up solving it by using a bash script wrapper function. It kills the PID after a timeout.
It's considered unsafe to kill or forcefully stop a Thread because it may leave the program in an undetermined state, which will later cause a crash or other more serious problem. Instead, you should design your worker thread to periodically check the interrupt flag via Thread#isInterrupted or Thread#interrupted and exit if it is set. Then, using another thread, you can signal to the worker thread that it should stop by calling interrupt() on the worker thread, which will result in the worker thread detecting the interrupt or possibly receiving an InterruptedException if it is blocking inside your code or the third party code.
Depending on how your thread is coded (ie. whether it would properly terminate when interrupted), you could use the provided Thread.join(millis) or Thread.join(mills, nanos) method calls.
Something like this:
Thread myThread
// ... start myThread
myThread.join(300000); // 5mins in millis
if (myThread.isAlive()) {
myThread.interrupt();
}
Inside the thread itself, you would want to ensure that you .yield() at relevant points and properly handle an InterruptedException to allow this kind of logic to work.
Of course this is an "ideal" kinda situation - if the thread is blocked due to some outside process, and cannot handle the .interrupt(), then it will not work very well.
HTH

How can I get the jobs that are in execution in a ScheduledThreadPoolExecutor?

I need to force the release of resources when a task is interrupted. For that, I implemented this solution. But with this, when I call shutdown() all the task in the ScheduledThreadPoolExecutor.getQueue() are forced correctly, but some of my jobs kept the resources. I checked very well the behavior and I figured out this: when a task is in execution, he is not present in the ScheduledThreadPoolExecutor queue (I know it sounds obvious). The problem is that I need to force the release of resources for all the jobs (in the queue or in execution)
So, How can I get the jobs that are in execution? Do you have a better idea?
You can maintain a list of all the Future's you create when you submit the jobs.
Use this list to cancel all futures.
Don't you want to call
executor.shutdownNow()
that will attempt to cancel currently running tasks (using Thread.interrupt so you'll need to implement an 'interruption policy' in each task that uses the interrupt flag).
from the 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.
This will return a list of waiting tasks, so you can always put this back onto a 'wait list' rather than loose them completely. You might also want follow that up with an 'await termination' to avoid run away code. For example, executor.awaitTermination(...).
tempus-fugit has some handy classes for handling this. You just call
shutdown(executor).waitingForShutdown(millis(400));
see here for details.
Also, the solution you outline in the blog post; I'm not sure if that's quite right. Future.cancel will only stop the task from being scheduled. If you were to update the example in the blog to allow interruption (ie cancel(true), it'd be equivalent (more or less) with the shutdownNow. That is to say, it will call interrupt on the underlying task which (if you've implemented an interruption policy) will stop it processing. As for cleaning up after interruption, you just need to make sure that you handle that appropriately within the interruption policy implementation. The upshot is that I think you can cancel and cleanup correctly using shutdownNow (or cancel(true))

Who is calling the Java Thread interrupt() method if I'm not?

I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be broken down into two questions:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt() on a Thread.
In practice, the normal use-cases for interrupt() involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.
Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit(). (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)
On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)
1) If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
One example is if your Runnable objects are executed using an ExecutorService and shutdownNow() is called on the service. And in theory, any 3rd-party thread pool or thread management framework could legitimately do something like this.
2) If I'm never ever interrupting other threads myself using interrupt() ... what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need analyze the codebase to figure out what is making the interrupt() calls and why. Once you have figured that out, you can work out what >>your<< part of the app needs to do.
Until you know why InterruptedException is being thrown, I would advise treating it as a hard error; e.g. print a stacktrace to the log file and shut down the app. (Obviously, that's not always the right answer ... but the point is that this is "a bug", and it needs to be brought to the attention of the developer / maintainer.)
3) How do I find out who / what is calling interrupt()?
There is no good answer to this. The best I can suggest is to set a breakpoint on the Thread.interrupt() and look at the call stack.
If you decide to integrate your code with other libraries, they can call interrupt() on your code. e.g. if you decide in the future to execute your code within an ExecutorService, then that may force a shutdown via interrupt().
To put it briefly, I would consider not just where your code is running now, but in what context it may run in the future. e.g. are you going to put it in a library ? A container ? How will other people use it ? Are you going to reuse it ?
As others have pointed out, interrupting a thread (actually, interrupting a blocking call) is usually used for purposes of exiting cleanly or cancelling an ongoing activity.
However, you should not treat an InterruptedException alone as a "quit command". Instead, you should think of interrupts as a means to control the running status of threads, much in the same way as Object.notify() does. In the same way that you'd check the current state after waking up from a call to Object.wait() (you don't assume that the wakeup means your wait condition has been satisfied), after being nudged with an interrupt you should check why you were interrupted. There is usually a way to do this. For example, java.util.concurrent.FutureTask has an isCancelled() method.
Code sample:
public void run() {
....
try {
.... // Calls that may block.
} catch (InterruptedException e) {
if (!running) { // Add preferred synchronization here.
return; // Explicit flag says we should stop running.
}
// We were interrupted, but the flag says we're still running.
// It would be wrong to always exit here. The interrupt 'nudge'
// could mean something completely different. For example, it
// could be that the thread was blocking on a read from a particular
// file, and now we should read from a different file.
// Interrupt != quit (not necessarily).
}
....
}
public void stop() {
running = false; // Add preferred synchronization here.
myThread.interrupt();
}
The problem with the question is "I". "I" usually refers to a single instance of a class. I mean by that, that any particular piece of low-level code (class) should not rely upon the implementation of the entire system. Having said that you do have make some "architectural" decisions (like what platform to run on).
Possible unexpected interrupts coming from the JRE are canceled tasks in java.util.concurrent and shutting down applets.
Handling of thread interrupts is usually written incorrectly. Therefore, I suggest the architectural decision to avoid causing interrupts where possible. However, code handling interrupts should always be written correctly. Can't take interrupts out of the platform now.
You could learn this by creating your own thread class (extending java.lang.Thread) and overriding interrupt() method, in which you record the stacktrace into, say, a String field, and then transfer to super.interrupt().
public class MyThread extends Thread {
public volatile String interruptStacktrace; // Temporary field for debugging purpose.
#Override
public void interrupt() {
interruptStacktrace = dumpStack(); // You implement it somehow...
super.interrupt();
}
}
As already mentioned, another library can interrupt your threads. Even if the library doesn't have explicit access to the threads from your code, they can still get the list of threads that are running and interrupt them that way with the following method.
I think I understand why you are a bit confused about interruption. Please consider my answers in line:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
Firstly you may interrupt other threads; I know that in JCiP it is mentioned that you should never interrupt threads you do not own; however, this statement has to be properly understood. What it means is that your code which might be running in any arbitrary thread should not handle interruption because since it is not the owner of the thread it has no clue of its interruption policy. So you may request interruption on other threads, but let its owner take the course of interruption action; it has the interruption policy encapsulated within it, not your task code; at least be courteous to set the interruption flag!
There are many ways why there could be interruptions still, may be timeouts, JVM interrupts etc.
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need to be very careful here; if you own the thread which threw InterruptedException (IE), then you know what to do upon catching it, say you may shutdown your app/service or you may replace this killed thread with a new one! However, if you do not own the thread then upon catching IE either rethrow it higher up the call stack or after doing something (may be logging), reset the interrupted status so that the code which owns this thread, when control reaches it, may learn that the thread was interrupted and hence take actions as it will since only it knows the interruption policy.
Hope this helped.
The InterruptedException says that a routine may be interrupted, but not necessarily that it will be.
If you don't expect the interrupt then you should treat it as you might any other unexpected exception. If it's in a critical section where an unexpected exception could have heinous consequences, it might be best to try and clean up resources and gracefully shutdown (because getting the interrupt signals that your well-engineered application that doesn't rely on interrupts is being used in a way it wasn't designed, and so there must be something wrong). Alternatively, if the code in question is something non-critical or trivial, you might want to ignore (or log) the interrupt and keep going.

Categories