Re: Making one or more threads wait for another to produce a value
or fail
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.
--232016332-1686931493-1306856815=:14714
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT
On Tue, 31 May 2011, Peter Duniho wrote:
On 5/31/11 7:00 AM, Tom Anderson wrote:
A Future<Verdict> looks ideal - it provides synchronisation, and a
value, and provides the same value to all requesters once it's
delivered, and also handles failure and cancellation. But i don't see
an easy way to make one for a simple value. There is FutureTask, but
that seems more geared to wrapping Callable and Runnable.
Any suggestions?
Personally, I'd just use the Object.wait() and Object.notifyAll() methods.
That probably is good enough. There are some subtleties: one has to be
aware of the possibility of spurious wakeup, and guard the wait() with a
suitable test; one has to think a bit about ensuring a happens-before
relationship between the setting of the result or exception variables and
their reading; there may be other things so subtle i haven't thought of
them. The nice thing about classes in java.util.concurrent is that they
come with an implicit contract that Doug Lea has already thought about the
subtleties for you. I love it when he does that.
I also don't see why FutureTask<Verdict> doesn't work for you (Future<V>
is just an interface???FutureTask<V> implements that interface);
FutureTask<Verdict> demands a Callable<Verdict>, which i'm not in a
position to supply. I am currently trying an approach using a do-nothing
Callable, but i am not happy about it.
just because you have more processing to do after delivering the value,
that doesn't necessarily mean that processing has to occur in the same
thread, does it?
In my case, Penelope is actually a framework thread running an event loop.
When the verdict arrives, it will be delivered to an event listener i
supply, but there is no way to get from there to returning a value from a
Callable.
Well, i suppose the listener could post the result to a BlockingQueue,
from which it would be read by a thread in a Callable, which could then
return it to its executor to fulfil a Future. But that seems a little
baroque.
(Alternatively, you could provide a custom implementation of Future<V>
that doesn't wrap a Runnable like FutureTask<V>, letting your thread
continue even after delivering the Future<V>???but such an implementation
would be more complicated than just using the wait()/notifyAll()
pattern,
Not *that* much more complicated, i don't think. Both varieties of get map
on to calls to their corresponding variety of wait in a loop guarded by a
call to isDone, and isDone maps on to a check on whether the verdict is
delivered. cancel/isCancelled would require code over and above the
simplest wait/notify implentation, but not a lot.
The thing that bugs me is that if this is so simple, and as generally
useful as i think it is, why isn't it in the JDK already?
so probably not worth the effort unless you expected to reuse the
implementation a lot).
Perhaps. Although implementing Future might be useful for documentation
purposes, because it immediately makes it clear what many of the methods
do.
It would be helpful if you could elaborate on why neither of those
simple, straightforward approaches satisfy your goals.
I hope i've explained myself a bit better now. I think writing my own
implementation of Future, as you suggest (well, as you imply - what you
actually suggest is not writing my own implementation of Future), may be a
good idea.
tom
--
Don't get me wrong, I'm a nutt case and proud of it, but I am also
safe. -- graham yukabuk.com
--232016332-1686931493-1306856815=:14714--