[concurrency-interest] Why does FutureTask hold reference to the Callable object forever?

Endre Stølsvik Online at stolsvik.com
Fri Jan 25 06:16:58 EST 2008

Tim Peierls wrote:
>     (and since you aren't supplied with the arguments of the initial
>     submit).
> Not sure how being supplied with those arguments would help you avoid 
> the need for a forwarding wrapper.

You could create the timing and reschedule-behaviour yourself, I 
envisioned. It was just one of many tries to get at that stupid 
Exception I obviously had in my code, but which STPE happily swallowed 
whole all the time.

>     I tried using this feature (the decorateTask-methods) to implement
>     Exception-catching by wrapping and overriding run(), but didn't
>     manage to do it in any way (it hits me now that you could possibly
>     proxy it and use the reflection stuff to change visibility of some
>     of those private methods to make it possible to invoke them?).
>     But such amazing wizardry is not what those methods are meant to
>     enable you to do, then?
> No.
> If you want to wrap submitted Runnables, why not wrap them *before* 
> submission? If you want to encapsulate that behavior in a 
> ScheduledExecutorService, you could write a 
> RunnableWrappingScheduledExecutorService that forwards to an underlying 
> STPE, but wraps any submitted Runnables using a protected method, 
> wrap(Runnable) that by default just returns the Runnable itself.

As mentioned, check:
   (The synopsis ain't mine - someone changed it.)

There I made a ScheduledThreadPoolExecutorWithExceptionListening.

   " However, after hours of banging my head while looking in vain for 
appropriate extension-points or listener-registration possibilities, I 
finally came up with an (obvious?) extension that simply overrides all 
submit-methods by wrapping up the submitted Callable or Runnable in a 
new instance of the same, which invokes the run/call in a try-catch, and 
runs notification to registered TaskExceptionListeners before throwing 
on (which hopefully should preserve contract - any Callables or 
Runnables laying in the queue are already "hidden" behind the internal 
RunnableScheduledFuture) "

And all this lard just because afterExecute wasn't made to include the 
Exception, but instead swallowing it. The workaround that Doug added 
2006-08-18 is still not a part of the javadoc as he suggested, and it 
also assumes that get() is idempotent.

See, my point is: when you SCHEDULE a task to be run in the future, or 
repeatedly, you don't sit around waiting for the Future. You fire and 
forget. And that class in its default setting simply swallows any 
badness happening, making bug hunting a nightmare, obviously in 
particular if you don't know about this, and don't quite see it coming.
   In the TPE, using execute(Runnable), first you get the Exception in 
afterExecture, THEN it is thrown on, so that the running Thread dies, 
spitting out the Exception on stderr per default. But with STPE, 
everything is *completely* different in these regards, even if you 
employ that same method.

To furthermore complicate the matter, one have the FutureTask's handling 
of "setException" - it doesn't work - there's a bug, it is acknowledged, 
a fix is made, and this was in 2006-08-26:

.. Read my description there: there is TWO things: first the obvious 
*bug*, but also a lack of some "getException" that could have been used 
in a "done()" override since the obvious option is broken. Although, if 
get() is idempotent, it would have worked to implement the same 
workaround as Doug describes, mentioned above

This set of classes and interfaces are not very straightforward, IMO. 
You pretty much HAVE to read the code to understand the workings, and 
doing that isn't all that easy with all the different interfaces and 
implementations of Callables, Runnables and Futures and whatnots. I 
personally feel I know those things now (which for STPE's case amounts 
to "don't use!"), but I'm just thinking poor newbies.


More information about the Concurrency-interest mailing list