[concurrency-interest] No *Task counterpart of CompletableFuture?

Tomas Mikula tomas.mikula at gmail.com
Tue Feb 11 18:32:02 EST 2014


On Wed, Feb 12, 2014 at 12:11 AM, √iktor Ҡlang <viktor.klang at gmail.com> wrote:
>
>
>
> On Tue, Feb 11, 2014 at 11:54 PM, Tomas Mikula <tomas.mikula at gmail.com>
> wrote:
>>
>> On Tue, Feb 11, 2014 at 11:22 PM, √iktor Ҡlang <viktor.klang at gmail.com>
>> wrote:
>> >
>> >
>> >
>> > On Tue, Feb 11, 2014 at 10:53 PM, Tomas Mikula <tomas.mikula at gmail.com>
>> > wrote:
>> >>
>> >> That's a good question and, as a matter of fact, I'm not even calling
>> >> any Future methods on the result. I think it's just because of my
>> >> current setting where I have other means of synchronization than
>> >> Future.get(), namely I'm using Platform.runLater() from JavaFX, like
>> >> this:
>> >>
>> >> res.thenAccept(r -> {
>> >>     Platform.runLater(() -> handle(r));
>> >> });
>> >>
>> >> I thought in other settings you would need to eventually call
>> >> Future.get() to synchronize with the main thread of computation.
>> >
>> >
>> > If you need to "synchronize with main thread" then you can always attach
>> > a
>> > CountDownLatch(1) as an on-complete callback and do countDown() there,
>> > and
>> > then do a timed wait on the CTD on the main thread.
>> >
>> > No need for Future.
>>
>> Thanks.
>>
>> It seems to me that with CountDownLatch there would be an extra work
>> to get the result of the asynchronous computation back to the main
>> thread.
>
>
> You said you wanted to synchronize with the main thread; not that you needed
> to return the result of the computation to it—hence my suggestion.
> Sorry for the noise.
>
>>
>>
>> Is Future.get() considered a bad practice?
>
>
> In my limited experience, blocking is usually the wrong solution to the
> problem, however, if you must _block_ the execution of the main thread and
> get the result of the Future out there and all you have is a CompletionStage
> I'd recommend stage.toCompletableFuture().get()

Thank you again. Right now I'm delivering the result to the JavaFX
application thread through Platform.runLater(), so there is no
blocking.
If I was writing a command line utility that uses my asynchronous
interface, I can imagine I would write the result to a file from
thenAccept(), so I would be able to avoid blocking, too.

>
>
>>
>>
>> Tomas
>>
>> >
>> >>
>> >>
>> >> Are you suggesting that
>> >> a) I should probably never need to call Future.get(); or
>> >> b) there's always CompletionStage.toCompletableFuture() (which I only
>> >> discovered now, so yes, I probably don't need Future)?
>> >>
>> >> Regards,
>> >> Tomas
>> >>
>> >> On Tue, Feb 11, 2014 at 10:20 PM, √iktor Ҡlang <viktor.klang at gmail.com>
>> >> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Tue, Feb 11, 2014 at 9:53 PM, Tomas Mikula
>> >> > <tomas.mikula at gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> On Tue, Feb 11, 2014 at 8:46 PM, Doug Lea <dl at cs.oswego.edu> wrote:
>> >> >> > On 02/10/2014 07:24 PM, Tomas Mikula wrote:
>> >> >> >>
>> >> >> >> Hi,
>> >> >> >>
>> >> >> >> I really like the addition of the CompletionStage interface in
>> >> >> >> 1.8.
>> >> >> >> However, there is just one implementation of it and that is
>> >> >> >> CompletableFuture. I am missing a task counterpart of it, i.e.
>> >> >> >> something that is both a Future and a CompletionStage, but is
>> >> >> >> completed by a computation (i.e. takes a Callable constructor
>> >> >> >> argument
>> >> >> >> or has a protected abstract compute() method).
>> >> >> >
>> >> >> >
>> >> >> > There are instead (four) static methods that accept functions and
>> >> >> > return
>> >> >> > a CompletableFuture that is complete after they run. For example
>> >> >> > supplyAsync is pasted below. Do you have usages in mind where
>> >> >> > you'd need something different?
>> >> >> >
>> >> >> >
>> >> >> >     /**
>> >> >> >      * Returns a new CompletableFuture that is asynchronously
>> >> >> > completed
>> >> >> >      * by a task running in the given executor with the value
>> >> >> > obtained
>> >> >> >      * by calling the given Supplier.
>> >> >> >      *
>> >> >> >      * @param supplier a function returning the value to be used
>> >> >> >      * to complete the returned CompletableFuture
>> >> >> >      * @param executor the executor to use for asynchronous
>> >> >> > execution
>> >> >> >      * @param <U> the function's return type
>> >> >> >      * @return the new CompletableFuture
>> >> >> >      */
>> >> >> >     public static <U> CompletableFuture<U> supplyAsync(Supplier<U>
>> >> >> > supplier,
>> >> >> >                                                        Executor
>> >> >> > executor)
>> >> >> >
>> >> >>
>> >> >> Thanks, Doug,
>> >> >>
>> >> >> turns out my research was too shallow. This is all I need to get the
>> >> >> job
>> >> >> done.
>> >> >>
>> >> >> There's just one minor wrinkle that I can live with. I am designing
>> >> >> an
>> >> >> asynchronous interface whose method should return something that is
>> >> >> both a Future and a CompletionStage, but not necessarily a
>> >> >> CompletableFuture, i.e. without the complete* methods. In other
>> >> >> words,
>> >> >> the interface should return something that completes on its own and
>> >> >> thus doesn't need the complete* methods. I don't want the client of
>> >> >> the interface to be able to call the complete* methods.
>> >> >>
>> >> >> I can accomplish this with
>> >> >>
>> >> >> interface Foo<T> {
>> >> >>     <U, F extends CompletionStage<U> & Future<U>> F foo(Function<T,
>> >> >> U>
>> >> >> f);
>> >> >> }
>> >> >>
>> >> >> which is slightly more verbose than (imaginary)
>> >> >>
>> >> >> interface Foo<T> {
>> >> >>     <U> CompletionFuture<U> foo(Function<T, U> f);
>> >> >> }
>> >> >>
>> >> >> where CompletionFuture is defined as suggested before:
>> >> >>
>> >> >> interface CompletionFuture<T> extends Future<T>, CompletionStage<T>
>> >> >> {}
>> >> >
>> >> >
>> >> > May I ask why it needs to implement Future?
>> >> >
>> >> >>
>> >> >>
>> >> >> Regards,
>> >> >> Tomas
>> >> >>
>> >> >> >
>> >> >> >>
>> >> >> >> I imagine a hierarchy like this:
>> >> >> >>
>> >> >> >> interface CompletionFuture<T> extends Future<T>,
>> >> >> >> CompletionStage<T>
>> >> >> >> {}
>> >> >> >>
>> >> >> >> class CompletableFuture<T> implements CompletionFuture<T> {...}
>> >> >> >>
>> >> >> >> class CompletionFutureTask<T> implements CompletionFuture<T> {
>> >> >> >>      public CompletionFutureTask(Callable<T> callable) {...}
>> >> >> >>      // or
>> >> >> >>      protected abstract T compute();
>> >> >> >> }
>> >> >> >>
>> >> >> >>
>> >> >> >> Is there a reason why this is missing? Is there a plan to add
>> >> >> >> this?
>> >> >> >>
>> >> >> >> Thanks,
>> >> >> >> Tomas
>> >> >> >> _______________________________________________
>> >> >> >> Concurrency-interest mailing list
>> >> >> >> Concurrency-interest at cs.oswego.edu
>> >> >> >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> >> >> >>
>> >> >> >
>> >> >> > _______________________________________________
>> >> >> > Concurrency-interest mailing list
>> >> >> > Concurrency-interest at cs.oswego.edu
>> >> >> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> >> >> _______________________________________________
>> >> >> Concurrency-interest mailing list
>> >> >> Concurrency-interest at cs.oswego.edu
>> >> >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > --
>> >> > Cheers,
>> >> > √
>> >> >
>> >> > ———————
>> >> > Viktor Klang
>> >> > Chief Architect - Typesafe
>> >> >
>> >> > Twitter: @viktorklang
>> >
>> >
>> >
>> >
>> > --
>> > Cheers,
>> > √
>> >
>> > ———————
>> > Viktor Klang
>> > Chief Architect - Typesafe
>> >
>> > Twitter: @viktorklang
>
>
>
>
> --
> Cheers,
>>
> ———————
> Viktor Klang
> Chief Architect - Typesafe
>
> Twitter: @viktorklang



More information about the Concurrency-interest mailing list