[concurrency-interest] Canceling Futures - Callable implementations

Joe Bowbeer joe.bowbeer at gmail.com
Tue Apr 7 17:34:18 EDT 2009


Peter,

My uses of ExecutorService tend to be centered around Future/Runnable tasks
rather than Callables, and I've always felt that the avenue for extension in
this area is through task customization.  Callable is supported as a
convenience, but it's not convenient in every situation...

What prevents you from executing your own tasks (e.g., MyTask)?  Or rather,
why do you think it's important to support a new flavor of Callable instead?

Joe

2009/4/7 Péter Kovács

> Joe,
>
> Thank you for your reply.
>
> I like your suggestion for a 'better "Callable"'. Couldn't it be
> included in the API with the ExecutorService et al. supporting it?
> Implementing against it would be, in a number of cases, much more
> straightforward than with the current apparatus.
>
> Thanks
> Peter
>
> On Tue, Apr 7, 2009 at 7:10 PM, Joe Bowbeer wrote:
> > Peter,
> >
> > Callable was designed to be useful stand-alone, like Runnable.  Because
> of
> > this, Callable has no more knowledge of its Future (if associated) than
> > Runnable has of its Thread, and therein lies the rub when one is trying
> to
> > write a Callable that knows the state of its Future.
> >
> > A better "Callable" for the purpose of detecting cancellation might have
> > been:
> >
> >   public interface MyCallable<V> {
> >       V call(Future task) throws Exception;
> >   }
> >
> > Then you could write "callables" of the form:
> >
> >   MyCallable<Integer> mc = new MyCallable<Integer>() {
> >       public Integer call(Future task) {
> >           while (!task.isCancelled()) {
> >               Thread.yield(); // Please!!
> >           }
> >           return 0;
> >       }
> >   };
> >
> > Below is a Task class that uses these instead:
> >
> > class MyTask<V> implements Future<V>, Runnable {
> >
> >     protected final FutureTask<V> task;
> >
> >     public MyTask(final MyCallable<V> mc) {
> >         task = new FutureTask<V>(new Callable<V>() {
> >             public V call() throws Exception {
> >                 return mc.call(task);
> >             }
> >         });
> >     }
> >
> >     /* Runnable implementation. */
> >
> >     public void run() {
> >         task.run();
> >     }
> >
> >     /* Future implementation. */
> >
> >     public boolean cancel(boolean mayInterruptIfRunning) {
> >         return task.cancel(mayInterruptIfRunning);
> >     }
> >
> >     public boolean isCancelled() {
> >         return task.isCancelled();
> >     }
> >
> >     public boolean isDone() {
> >         return task.isDone();
> >     }
> >
> >     public V get() throws InterruptedException, ExecutionException {
> >         return task.get();
> >     }
> >
> >     public V get(long timeout, TimeUnit unit)
> >         throws InterruptedException, ExecutionException, TimeoutException
> {
> >         return task.get(timeout, unit);
> >     }
> > }
> >
> > This internal FutureTask construction is also found in SwingWorker, by
> the
> > way.
> >
> > Joe
> >
> > 2009/4/7 Péter Kovács
> >>
> >> Hi,
> >>
> >> How will a Callable implementation know that the corresponding Future
> >> has been canceled?
> >>
> >> One mechanism I am aware of is thread interruption, but practice shows
> >> that relying on this mechanism is highly unsafe. For interruption
> >> checks to work safely, everyone up the call stack would have to
> >> observe the related protocol, which is rarely the case.
> >>
> >> Is there anything else in place for this purpose? If there is not,
> >> wouldn't it be reasonable to provide a "useful" default implementation
> >> of Callable -- along the lines of FutureTask being an implementation
> >> of Future?
> >>
> >> Thanks
> >> Peter
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20090407/6f3ab833/attachment.html>


More information about the Concurrency-interest mailing list