Java: Logging FutureTask exceptions - java

I've got an application which regularly submits tasks to be executed in a dedicated thread. Those tasks are FutureTask<V> and the thread is no more than an infinite loop which executes the jobs as they get into a queue, going to sleep if empty.
Sometimes I need to wait for the result of a computation, so I call FutureTask's get() method, which will also throw an exception if something bad happened. But there are cases where I don't care what the result was, if any, but I need to know (log, printStackTrace() or whatever...) if there was some kind of failure during the task execution.
Is there any way I could achieve this without having to wait on a get() that I don't need?
Thanks in advance!
UPDATE: Calling get() on the runner thread after executing the task seemed to be the only way to catch the exception if no one else would wait for the result.
Another solution would be extending FutureTask class to provide a method which, via java reflection, exposes sync.exception private field.

If I understand your problem correctly, there is a simple solution. Modify your dedicated task-runner thread to call Future.get() after running each task, and catch and log the ExecutionException (if any).
Note that calling get in the task-runner thread after running the task is guaranteed not to block.
(Uncaught exception handlers won't help because any exception and error thrown by the run() method of the future's wrapped Runnable will be caught byFutureTask.run()`.)

Check Thread.UncaughtExceptionHandler

I think you should use 'setException' to report the failure from your task. It will make get() report an ExecutionException. See this as well:
How to catch exceptions in FutureTask

A CompletionService might be a possibility here. Using one of those will allow you to call get() on the Futures once they are definitely finished. Alternatively, the Guava libraries have ways to add a listener to a Future or FutureTask to execute when the task is complete (the ListenableFuture and its related objects).

You can also check an example I wrote for Futuretask

Related

How can I gracefully end execution in a java executor without returning or using an exception?

I have codebase that calls a black box, that in turn calls other code I have control of, call it thing.innerMethod(). The code in the black box needs to execute in a different thread than the code that calls it, so I have decided to use an executor:
Future<String> bbFuture = executorService.submit(() -> {
return blackBox.doStuff(thing);});
If the execution takes too long, the user might call another endpoint that ultimately calls bbFuture.cancel(), triggering a CancellationException in the thread with the future and an InterruptedException in the thread running inside the executor.
The problem is that when the InterruptedException propagates into the black box, it catches it and logs it a stack trace, and raises false alarms. I don't need to catch every InterruptedException, but I know a place I could put a catch that would get probably 90% of them. The problem is I don't really have a good way to stop execution without returning from the function, and any partial or dummy result would probably trigger another exception. I know I could use Thread.currentThread().stop(), but stop() is deprecated.
How can I stop execution inside a java executor without returning or throwing an exception?
You can choose to run the task user wants to cancel by wrapping the future into another object which implements cancel() request and do not delegate the user given cancel request to the underlying future instance. In this case, the task will run as normal. (Trick user that the task cancelled but run in background and do not care the result of the task -- If the task has side-effect, this might not be desirable) -- will use computing resources.
If you want the task to be responsive to interruption, then you should use the regular way of cancelling a task, namely notify the task that it should no longer continue by future.cancel() and the task you are notifying should be coded in a way that detects interruptions and clears any state required and return. (return something like an empty result, a special result etc.)
NOTE: future.cancel() sets a specific boolean field in Thread class. Some blocking library functions throws InterruptedException in the entry before doing something. For instance, Thread.sleep function might look to see if the boolean flag is set and throw InterruptedException without waiting, or it might wait and somehow detect the cancellation request before waiting to the end and throw InterruptedException. Or it might not detect at all. In this case, you should check regulary through out the task that if the task cancelled. [ using Thread.currentThread().isInterrupted()]

Advantage of directExecutor

As far as I understand Guava's MoreExecutors.directExecutor() creates an Executor which will executes the runnable before the execute method call could return.
What are the usecases that need direct executor ? Can't the caller directly call runnable.run() directly instead of the extra level of indirection by creating an executor and submitting the runnable to this executor ? May be I am missing the real purpose of it's existence. I wanted to understand in what case is this useful.
There are few places which require both Runnable and Executor.
One of then is for example ListenableFuture and its addListener method. The only way how to execute listener immediately within the same thread is to provide direct executor.
MoreExecutors.directExecutor() is useful when you call an API that requires you to specify an executor to execute the task (e.g. Futures.transform(), listenableFuture.addListener(), etc).
Note that when you use directExecutor() with these APIs, the runnable may be run on one of these two threads:
The thread that completes the previous future
The thread that calls transform()/addListener()
This uncertainty could cause unexpected issues. So be careful when you use directExecutor().

Non-cancellable futures returned by a thread-pool. Do they exist?

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.

Killing Thread without periodically checking alive status

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. :)

Should I call cancel(true) on Future<?> or my own FutureTask

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.

Categories

Resources