I have a custom class MyFutureTask extends FutureTask<Void> upon which I do some code on the done() method.
I use an ExecutorService which I call submit(new MyFutureTask()) into it.
Now I can keep a reference to the Future<?> that gets returned after you call submit, but when I call cancel to that the isCancelled() method never returns true.
Should I ignore the Future<?> object that gets returned and instead work with MyFutureTask and call cancel(true) on that instead?
What is the use of the Future<?> object then?
edit: What's the difference between Future and FutureTask in Java? from this thread I understand the difference.
Besides the default cancel behavior I also want to attempt to stop a network call in progress so I guess the route I am going to use FutureTask is correct. Someone can confirm?
Don't use Executor.submit, instead use Executor.execute since you already have a Future. When you call submit, you are just needlessly wrapping your FutureTask in another FutureTask.
Also you can't "stop" a network trip. You have to wait until it returns or times out. What you do is call Future.cancel(true), then when your network trip returns look and see if the future has been canceled Future.isCancelled(). THen you can just stop doing what you were doing in the Future. For all intents and purposes it's the same effect as if you could cancel a network trip. To the end user (ie the client code or caller) it will appear the same way. The only side effect you might notice is if you have only a single thread executing tasks in which case the thread waiting on the network trip has to return before it will pick up the next task. If that's a problem using a pool of threads.
As an aside if you used NIO or some library thereof you could stop waiting on the result immediately, but that's a lot more work to code up.
Related
I'm currently implementing a service that works in a concurrent setting and that has as operations a bunch of blocking methods.
I would like to change that so they return a Future<?> instead and it's up to the client to decide whether he wants to execute get() and block the thread or not. The problem is that Future<?> brings baggage, ie, it is possible to invoke cancellation on a future. But if that were to actually happen then it would most probably break my service's invariants.
Is there any easy way to make a thread-pool return non-cancellable futures? Currently, the only solution I'm seeing is wrapping the thread-pool future's into a future of mine that will throw an UnsupportedException if some attempts to cancel the operation. Or just return an object of my own, but I'd like to KISS if possible.
I think, you fear too much. I see two VERY simple solutions:
decorate (wrap) the default FutureTask and override in your ExecutorService the newTaskFor() method returning your new class.
do nothing, i.e do not cancel any work in your Callables or Runnables. In order to make your life easier you could take a look at Guava's uninterruptibles.
Long story short: I have a collection of Future objects. Some of them are already in progress, some are not. I iterate the collection and call future.cancel(false) which, according to the documentation, should cancel all Futures that are not currently running but should allow all the others to complete.
My question is: How do I know when a particular Future is completed after I have called future.cancel(false)? future.isDone() always returns true because cancel() was indeed called before that and future.get() always throws a CancellationException even though the Future is still running.
Any suggestions?
Since Future models the future result of a pending computation, and since that result is not forthcoming from a canceled future, it is reasonable that Future gives you no way to find out when the computation whose result has been disposed of will complete. In other words, you'd need another paradigm to achieve your goal with that approach.
If your wish is to wait for all the submitted tasks to complete, the closest thing which is directly supported by the Executor Service API is to shut down the entire executor service and wait for its termination.
If the above does not fit your solution, then I don't see a better approach than some custom solution, for example a custom implementation of Runnable, which does some housekeeping on the side so you can check when it has completed running.
You could add a flag to your Future implementation which will reflect the actual Future' state
given a Callable<Object> c:
futureTask1 = new FutureTask<Object>(c);
futureTask2 = new FutureTask<Void>(futureTask1, null);
executor.execute(futureTask2);
now if you want the result:
futureTask1.get()
if you're no longer interested in the result:
futureTask1.cancel(mayInterruptIfRunning)
if you want to wait to be sure the code in the callable is not (and will not become) running (whether never called, finished cancelling or finished producing the result):
futureTask2.get()
Even if cancelled before it started working, this waits for the executor to execute the scheduled task (which will to nothing if already cancelled), so this may unnecessariliy wait for other long-running tasks to complete. YMMV
I am runnning ExecutorService to perform a heavy computation, however I don't want to pollute the algorithmic class/method code with runner operations, in this case I'd like to do periodical check if it should be terminated gracefully.
I tried to search for solutions, still with no success, what I concluded is that this is not possible because only the thread itself is allowed to "autokill himself".
So my question is, if there is any way to terminate the thread "outside" of the thread by invoking some forcefull atempt to kill the thread.
If not maybe the best solution is to use aspect and intercept each iteration by adding a kill status check ?
You can call thread.interrupt(). This can cause thread to exit if it "respects" interruptions. For example if thread is blocked on IO or on wait() or on sleep() InterruptedExcption will be thrown. However if it is "blocked" on busy loop that does not check isInterrupted() flag interruption will not work.
Other way to indeed kill the thread is to call deprecated method stop(). However this is the last possibility. This method is deprecated because it indeed kills threads immediately (like kill -9) that can cause resource leaks.
Bottom line: to be able to stop threads grecefully you have to write code that is ready for this and the standard solution is to respect thread interrupts.
There sure is a way to forcefully terminate a thread: Thread#stop, but it is almost never advisable. Your idea with aspects seems quite fruitful, but if you have any sort of a main loop in your task, then consider replacing the loop with a series of submitted tasks where each task is one iteration. This will allow ExecutorService#shutdown to interrupt the processing. All state can be carried along in the instance of Runnable that is being submitted.
I haven't used the ExecutorService much. But reading the JavaDocs it appears that you submit a callable or runnable to the service. Those methods return a Future object which have a cancel method on it.
cancel(boolean mayInterruptIfRunning)
Have you tried using that?
The method thread.interrupt() stop the thread and you can call it outside the thread itself!
If you do not want to change the original implementation, you could wrap the thread. I'm not very familar with Java, so I'm sorry for the obviously not compiling example:
class ThreadWrapper extends Thread {
public ThreadWrapper(Thread t, TerminateCallback c) {
// ...
}
#Override
public void run() {
t.start(Thread.SYNCHRONOUS);
c.done(this);
}
}
You'd need to implement TerminateCallback yourself. I also assume there is a way to start a thread synchronously, Thread.SYNCHRONOUS is just a place holder. If this condition is fulfilled, I'm sure you can transfer it into valid code. :)
I use ThreadPoolExecutor to run some actions, at some time I cancelled some future tasks and stored it into a list to arrange some other tasks to do, and after that I want to reactive the saved cancelled future tasks.
But the problem is when I submit the task into the pool, it would not be executed, looks like the cancelled or done flag is saved and recognized by the thread executor, and thus that thread would not be called.
What should I do?
The FutureTask implementation maintains the canceled state. Essentially, when the run() method is called again, it does a CAS operation which fails since the state is not runnable and returns immediately without invoking the inner Callable's call() method. I couldn't see a way to retrieve the original Callable out of it or restore the FutureTask to a non-canceled state.
In response to what should you do...
Do you have to cancel them? Why not let them run? If you want priority execution, could you try creating your ThreadPoolexecutor with a PriorityBlockingQueue and use a Comparator to establish the priority. This will allow tasks to be executed in the proper order since they will be added to the PriorityBlockingQueue based on the results of the Comparator.
Use Runnable instead of threads. The execution pool can handle a Runnable the same way a Thread, but a Runnable could be rerunned number of times.
If you want to have a return value you can use a Callable. http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
I am writing an application in java (1.6) using swing. I currently have a JXBusyLabel on a JXLayer over the content area of my program acting as a busy indicator. I want to provide a way to allow others working with me to create a task that pops up the busy label while it's executing. The catch is, the task must be cancel-able. What is the best way to expose the functionality I desire?
Some ideas I've come up with:
Raw access to setBusy()
This is obviously the easiest for me but requires users know and understand swing threading issues.
public <T> Future<T> execute(Callable<T>)
Wraps the callable in a FutureValue that is run() on a separate thread and returns that FutureValue. The question then becomes, how to keep track of all FutureValue's generated and how to ensure that they can be cancelled. (e.g. cancel(true) always cancels)
I have never used the concurrency package in Java before and it didn't exist back when I 'learned' Java. So I am open to completely new and different ways of implementing this functionality.
Edit:
Clarification of my question. I know about SwingWorker. I've just never used it. What I want to know is this:
Given a Callable (Java version of a closure?) How can I:
Return the value of call() to the user w/o blocking (I think I need to use a Future for this)
Tell the JXLayer to lock (starts painter), execute the supplied callable, and then unlock the JXLayer (stops painter)
Ensure that, no matter what thread calls my busyExec() function, the GUI remains responsive and the background task completes. (NOTE: If I return some sort of Future object and they call get() on the event thread, it can/will block and that is ok)
I guess my main stumbling point is how to implement #2. Should I have busyExec() spin off a new thread that blocks until no background tasks are running? Should I try for some sort of queue. Is there an object that will do this all for me already?
The SwingWorker (of Java 6) implements Future so it seems like it has the ability to cancel tasks via the cancel method.
More information on SwingWorker from The Java Tutorials:
Lesson: Concurrency in Swing
Worker Threads and SwingWorker
Canceling Background Tasks
Okay. For anyone interested here is what I am currently using to implement my request.
I have a method that will take a Callable<T>. It then creates a FutureTask<T> this will be returned to the caller as a this as a Future<T>. The JXBusyLabel and JXLayer are told to start painting and to lock the ui. The FutureValue and Thread (see below) is enqueued in a special list. A Runnable is created that: calls run() on the FutureTask, removes the FutureValue (and thread) from the list, and if the list is empty, unlocks the JXLayer and stops the JXBusyLabel. This Runnable is launched in a new Thread with normal priority.
When the user hits the cancel button. The list is iterated over and the FutureTasks are all canceled and removed from the list if they could be cancelled. First try cancel(false), then cancel(true). If both those means fail, the user is prompted with a warning asking them if they want to Thread.stop() the task and explains that this could make the app unstable. If yes, stop() the thread running the task. This might bring the app down. In all cases, the UI is unlocked.
The documentation for other team members states that they must be aware that the task can be killed. They are not to call get() until isDone() is true. They are explicitly told that this will basically force them to block until the task is done or cancelled. So they can't call it from the event dispatch thread.
Other solutions are still welcome