[concurrency-interest] JCiP Memoizer

Tim Peierls tim at peierls.net
Wed Oct 18 08:51:06 EDT 2006


One of the things that makes the Memoizer example so interesting (and
suitable for inclusion in chapter 5 of JCiP) is that it is a rare example of
FutureTask used outside of an Executor.

Does David's last fix with additional interrupt checking in the Callable
adapter do the trick? Something like this:

    public V compute(final A arg) throws InterruptedException {
        while (true) {
            Future<V> f = cache.get(arg);
            FutureTask<V> ft = null;
            if (f == null) {
                Callable<V> eval = new Callable<V>() {
                    public V call() throws InterruptedException {
                        V result = c.compute(arg);
                        if (Thread.interrupted())
                            throw new InterruptedException();
                        return result;
                    }
                };
                FutureTask<V> ft = new FutureTask<V>(eval);
                f = cache.putIfAbsent(arg, ft);
                if (f == null) {
                    f = ft;
                    ft.run();
                } else {
                    ft = null;
                }
            }
            try {
                return f.get();
            } catch (CancellationException e) {
                throw new IllegalStateException("can't have been
cancelled"); // ??
            } catch (ExecutionException e) {
                Throwable t = e.getCause();
                if (t instanceof InterruptedException) { // ft.run()
was interrupted
                    cache.remove(arg,f);
                    if (ft != null)  // we did ft.run() so we were interrupted
                        throw (InterruptedException) t;
                    // else retry
                } else {
                    throw launderThrowable(t);
                }
            }
        }
    }


Yuck. Makes that final example a lot harder to explain than we were hoping
for.

--tim


On 10/18/06, Joe Bowbeer <joe.bowbeer at gmail.com> wrote:
>
> I think the existing cancellation exception handling would make more
> sense if the task were submitted to an executor.  Then a forced
> shutdown of the executor, for example, could cause a cancellation
> exception.
>
> Btw, when I've coded this kind of thing in the past, I've usually
> finessed the problem by adding "throws Exception" to the method in
> question :-)
>
> On 10/18/06, David Holmes <dcholmes at optusnet.com.au> wrote:
> > Alex,
> >
> > I have to concur with Tim. The intent was that interruption during
> ft.run()
> > implied cancellation and so there was a need to do clean-up of the cache
> > entry. But there is nothing to convert the interruption to a cancel()
> > request and so all that happens in the current case is that everyone who
> > calls f.get() will get ExecutionException with a cause of
> > InterruptedException.
> >
> > [...]
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20061018/229cf12e/attachment.html 


More information about the Concurrency-interest mailing list