Reusing CompletableFuture

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Reusing CompletableFuture

Pavel Rappo
Hi,

Is it generally safe to reuse an instance of CompletableFuture? Or am I risking
with memory leaks due to dependants build up?

Say, I have a method that returns a CF. In some cases it may return a CF
straight away indicating that the action has been already done. Should I always
create a new completed CF, or can I reuse a pre-cached one?

There's a comment in the class itself, but I'm not sure I understand it enough
to make a conclusion:

     * ...Without precautions, CompletableFutures would be prone to
     * garbage accumulation as chains of Completions build up, each
     * pointing back to its sources. So we null out fields as soon as
     * possible.  The screening checks needed anyway harmlessly ignore
     * null arguments that may have been obtained during races with
     * threads nulling out fields.  We also try to unlink non-isLive
     * (fired or cancelled) Completions from stacks that might
     * otherwise never be popped: Method cleanStack always unlinks non
     * isLive completions from the head of stack; others may
     * occasionally remain if racing with other cancellations or
     * removals...

Thanks,
-Pavel
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Martin Buchholz-3
Don't reuse CompletableFutures.
Most obviously because they're mutable.

On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
Hi,

Is it generally safe to reuse an instance of CompletableFuture? Or am I risking
with memory leaks due to dependants build up?

Say, I have a method that returns a CF. In some cases it may return a CF
straight away indicating that the action has been already done. Should I always
create a new completed CF, or can I reuse a pre-cached one?

There's a comment in the class itself, but I'm not sure I understand it enough
to make a conclusion:

     * ...Without precautions, CompletableFutures would be prone to
     * garbage accumulation as chains of Completions build up, each
     * pointing back to its sources. So we null out fields as soon as
     * possible.  The screening checks needed anyway harmlessly ignore
     * null arguments that may have been obtained during races with
     * threads nulling out fields.  We also try to unlink non-isLive
     * (fired or cancelled) Completions from stacks that might
     * otherwise never be popped: Method cleanStack always unlinks non
     * isLive completions from the head of stack; others may
     * occasionally remain if racing with other cancellations or
     * removals...

Thanks,
-Pavel
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Viktor Klang

A possible solution is to return CompletionStage rather than CompletableFuture.

--
Cheers,


On Jul 24, 2016 18:23, "Martin Buchholz" <[hidden email]> wrote:
Don't reuse CompletableFutures.
Most obviously because they're mutable.

On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
Hi,

Is it generally safe to reuse an instance of CompletableFuture? Or am I risking
with memory leaks due to dependants build up?

Say, I have a method that returns a CF. In some cases it may return a CF
straight away indicating that the action has been already done. Should I always
create a new completed CF, or can I reuse a pre-cached one?

There's a comment in the class itself, but I'm not sure I understand it enough
to make a conclusion:

     * ...Without precautions, CompletableFutures would be prone to
     * garbage accumulation as chains of Completions build up, each
     * pointing back to its sources. So we null out fields as soon as
     * possible.  The screening checks needed anyway harmlessly ignore
     * null arguments that may have been obtained during races with
     * threads nulling out fields.  We also try to unlink non-isLive
     * (fired or cancelled) Completions from stacks that might
     * otherwise never be popped: Method cleanStack always unlinks non
     * isLive completions from the head of stack; others may
     * occasionally remain if racing with other cancellations or
     * removals...

Thanks,
-Pavel
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Pavel Rappo
In reply to this post by Martin Buchholz-3
Hi Martin,

Quite a strong statement. I don't think an isolated fact of mutability
of an entity precludes us from reusing this entity (pool of objects?
reusable buffers?).

You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
value), right? In my example the CF was returned by an API to a user
and this CF was completed prior to be returned.

On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:

> Don't reuse CompletableFutures.
> Most obviously because they're mutable.
>
> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>
> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>
>> Hi,
>>
>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>> risking
>> with memory leaks due to dependants build up?
>>
>> Say, I have a method that returns a CF. In some cases it may return a CF
>> straight away indicating that the action has been already done. Should I
>> always
>> create a new completed CF, or can I reuse a pre-cached one?
>>
>> There's a comment in the class itself, but I'm not sure I understand it
>> enough
>> to make a conclusion:
>>
>>      * ...Without precautions, CompletableFutures would be prone to
>>      * garbage accumulation as chains of Completions build up, each
>>      * pointing back to its sources. So we null out fields as soon as
>>      * possible.  The screening checks needed anyway harmlessly ignore
>>      * null arguments that may have been obtained during races with
>>      * threads nulling out fields.  We also try to unlink non-isLive
>>      * (fired or cancelled) Completions from stacks that might
>>      * otherwise never be popped: Method cleanStack always unlinks non
>>      * isLive completions from the head of stack; others may
>>      * occasionally remain if racing with other cancellations or
>>      * removals...
>>
>> Thanks,
>> -Pavel
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Pavel Rappo
In reply to this post by Viktor Klang
In my experience, get() and join() are too precious to lose them and
CompletionStage.toCompletableFuture is too weakly defined (UOE) to be
relied upon. So either people will do everything in an async fashion
or they will come up with some tricks like:

CompletionStage<?> cs = null;
CompletableFuture<?> cf =
CompletableFuture.completedFuture(null).thenCompose(x -> cs);

On Sun, Jul 24, 2016 at 7:07 PM, Viktor Klang <[hidden email]> wrote:

> A possible solution is to return CompletionStage rather than
> CompletableFuture.
>
> --
> Cheers,
> √
>
>
> On Jul 24, 2016 18:23, "Martin Buchholz" <[hidden email]> wrote:
>>
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]>
>> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>      * ...Without precautions, CompletableFutures would be prone to
>>>      * garbage accumulation as chains of Completions build up, each
>>>      * pointing back to its sources. So we null out fields as soon as
>>>      * possible.  The screening checks needed anyway harmlessly ignore
>>>      * null arguments that may have been obtained during races with
>>>      * threads nulling out fields.  We also try to unlink non-isLive
>>>      * (fired or cancelled) Completions from stacks that might
>>>      * otherwise never be popped: Method cleanStack always unlinks non
>>>      * isLive completions from the head of stack; others may
>>>      * occasionally remain if racing with other cancellations or
>>>      * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Martin Buchholz-3
In reply to this post by Pavel Rappo
Arguing for the other side ...

A completed future will never have a chain of dependent completions build up because they will all be triggered, and if the future was already completed any continuation will be executed immediately.

It may make sense to reuse CompletableFutures where the mutability has been removed, e.g. by subclassing.
Are we safe if we override just obtrudeValue and obtrudeException on a completed future?
Should j.u.c. provide such a thing?
Should j.u.c. provide separate classes for providers and consumers (read only!) of the future value?

On Sun, Jul 24, 2016 at 11:11 AM, Pavel Rappo <[hidden email]> wrote:
Hi Martin,

Quite a strong statement. I don't think an isolated fact of mutability
of an entity precludes us from reusing this entity (pool of objects?
reusable buffers?).

You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
value), right? In my example the CF was returned by an API to a user
and this CF was completed prior to be returned.

On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
> Don't reuse CompletableFutures.
> Most obviously because they're mutable.
>
> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>
> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>
>> Hi,
>>
>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>> risking
>> with memory leaks due to dependants build up?
>>
>> Say, I have a method that returns a CF. In some cases it may return a CF
>> straight away indicating that the action has been already done. Should I
>> always
>> create a new completed CF, or can I reuse a pre-cached one?
>>
>> There's a comment in the class itself, but I'm not sure I understand it
>> enough
>> to make a conclusion:
>>
>>      * ...Without precautions, CompletableFutures would be prone to
>>      * garbage accumulation as chains of Completions build up, each
>>      * pointing back to its sources. So we null out fields as soon as
>>      * possible.  The screening checks needed anyway harmlessly ignore
>>      * null arguments that may have been obtained during races with
>>      * threads nulling out fields.  We also try to unlink non-isLive
>>      * (fired or cancelled) Completions from stacks that might
>>      * otherwise never be popped: Method cleanStack always unlinks non
>>      * isLive completions from the head of stack; others may
>>      * occasionally remain if racing with other cancellations or
>>      * removals...
>>
>> Thanks,
>> -Pavel
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Doug Lea
On 07/24/2016 03:32 PM, Martin Buchholz wrote:

> It may make sense to reuse CompletableFutures where the mutability has been
> removed, e.g. by subclassing.
> Are we safe if we override just obtrudeValue and obtrudeException on a completed
> future?
> Should j.u.c. provide such a thing?

It takes a long enough time to put out major releases that it is easy
to forget that this has been in CompletableFuture for almost a year,
but still not routinely available until jdk9:

     /**
      * Returns a new CompletionStage that is already completed with
      * the given value and supports only those methods in
      * interface {@link CompletionStage}.
      *
      * @param value the value
      * @param <U> the type of the value
      * @return the completed CompletionStage
      * @since 9
      */
     public static <U> CompletionStage<U> completedStage(U value) {
         return new MinimalStage<U>((value == null) ? NIL : value);
     }


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Viktor Klang
In reply to this post by Pavel Rappo

Personally, I'd recommend avoiding blocking at "all" cost.

When there's a qualified need to use .get() and .join(): create a new CompletableFuture which will be completed by the returned CompletionStage (this is not a trick!).

--
Cheers,


On Jul 24, 2016 20:18, "Pavel Rappo" <[hidden email]> wrote:
In my experience, get() and join() are too precious to lose them and
CompletionStage.toCompletableFuture is too weakly defined (UOE) to be
relied upon. So either people will do everything in an async fashion
or they will come up with some tricks like:

CompletionStage<?> cs = null;
CompletableFuture<?> cf =
CompletableFuture.completedFuture(null).thenCompose(x -> cs);

On Sun, Jul 24, 2016 at 7:07 PM, Viktor Klang <[hidden email]> wrote:
> A possible solution is to return CompletionStage rather than
> CompletableFuture.
>
> --
> Cheers,
> √
>
>
> On Jul 24, 2016 18:23, "Martin Buchholz" <[hidden email]> wrote:
>>
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]>
>> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>      * ...Without precautions, CompletableFutures would be prone to
>>>      * garbage accumulation as chains of Completions build up, each
>>>      * pointing back to its sources. So we null out fields as soon as
>>>      * possible.  The screening checks needed anyway harmlessly ignore
>>>      * null arguments that may have been obtained during races with
>>>      * threads nulling out fields.  We also try to unlink non-isLive
>>>      * (fired or cancelled) Completions from stacks that might
>>>      * otherwise never be popped: Method cleanStack always unlinks non
>>>      * isLive completions from the head of stack; others may
>>>      * occasionally remain if racing with other cancellations or
>>>      * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> [hidden email]
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Pavel Rappo
In reply to this post by Doug Lea
Hi Doug,

Pardon me, are you sure you replied to Martin rather than to Viktor?
Viktor has suggested using CS instead of CF. What Martin has asked is
whether it makes sense to have something which is-a CompletableFuture
but without the "obtrude" logic.

On Sun, Jul 24, 2016 at 8:41 PM, Doug Lea <[hidden email]> wrote:

> On 07/24/2016 03:32 PM, Martin Buchholz wrote:
>
>> It may make sense to reuse CompletableFutures where the mutability has
>> been
>> removed, e.g. by subclassing.
>> Are we safe if we override just obtrudeValue and obtrudeException on a
>> completed
>> future?
>> Should j.u.c. provide such a thing?
>
>
> It takes a long enough time to put out major releases that it is easy
> to forget that this has been in CompletableFuture for almost a year,
> but still not routinely available until jdk9:
>
>     /**
>      * Returns a new CompletionStage that is already completed with
>      * the given value and supports only those methods in
>      * interface {@link CompletionStage}.
>      *
>      * @param value the value
>      * @param <U> the type of the value
>      * @return the completed CompletionStage
>      * @since 9
>      */
>     public static <U> CompletionStage<U> completedStage(U value) {
>         return new MinimalStage<U>((value == null) ? NIL : value);
>
>     }
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Doug Lea
On 07/24/2016 04:20 PM, Pavel Rappo wrote:
> Viktor has suggested using CS instead of CF. What Martin has asked is
> whether it makes sense to have something which is-a CompletableFuture
> but without the "obtrude" logic.

And others have had other opinions about exactly which methods
to allow in read-only-ish contexts (googling will find 4 different
discussions on this list). So for jdk9, we predefine the most minimal
one, and make it relatively easy to define others. So I think we
have all the possibilities covered; some more easily by users
than others. See the example in class-level javadocs:

http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/CompletableFuture.html

-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Alex Otenko
In reply to this post by Pavel Rappo
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Pavel Rappo
True. In my particular use case this property is satisfied.

On Thursday 28 July 2016, Alex Otenko <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;pavel.rappo@gmail.com&#39;)">pavel.rappo@...> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;martinrb@google.com&#39;)">martinrb@...> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;pavel.rappo@gmail.com&#39;)">pavel.rappo@...> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> <a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;Concurrency-interest@cs.oswego.edu&#39;)">Concurrency-interest@...
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> <a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;Concurrency-interest@cs.oswego.edu&#39;)">Concurrency-interest@...
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Viktor Klang
In reply to this post by Alex Otenko

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Alex Otenko
What is? Reusability?

I don’t know about CompletableFuture specifically, but mutability has an immense impact on the implementation, since reuse requires knowing that the mutator repurposing the structure is the last entity looking at it in the old guise. Then there are gotchas that whoever keeps a reference to it, must also have a way of knowing which version of the thing it is looking at - like, suddenly you are not allowed to pass around CompletableFuture uncontrollably, need to devise ways to solve ABA problem - which becomes a problem due to mutability.

Alex

On 28 Jul 2016, at 16:17, Viktor Klang <[hidden email]> wrote:

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Viktor Klang
For the CompletableFuture itself: I recommended sharing it as a CompletionStage instead, since that is not mutable.
For the value of the CompletionStage/CompletableFuture, same rules apply to most concurrent datastructures: instances made available through it needs to either be immutable, thread-safe or the usage predictably harmless. :)

On Thu, Jul 28, 2016 at 8:26 PM, Alex Otenko <[hidden email]> wrote:
What is? Reusability?

I don’t know about CompletableFuture specifically, but mutability has an immense impact on the implementation, since reuse requires knowing that the mutator repurposing the structure is the last entity looking at it in the old guise. Then there are gotchas that whoever keeps a reference to it, must also have a way of knowing which version of the thing it is looking at - like, suddenly you are not allowed to pass around CompletableFuture uncontrollably, need to devise ways to solve ABA problem - which becomes a problem due to mutability.

Alex

On 28 Jul 2016, at 16:17, Viktor Klang <[hidden email]> wrote:

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Josh Humphries
Unfortunately -- unless you create a defensive copy or use a custom subclass of CompletableFuture -- it is mutable, even as CompletionStage:

stage.toCompletableFuture().obtrudeValue(null);



----
Josh Humphries
Payments Engineering
Atlanta, GA  |  678-400-4867

On Thu, Jul 28, 2016 at 3:04 PM, Viktor Klang <[hidden email]> wrote:
For the CompletableFuture itself: I recommended sharing it as a CompletionStage instead, since that is not mutable.
For the value of the CompletionStage/CompletableFuture, same rules apply to most concurrent datastructures: instances made available through it needs to either be immutable, thread-safe or the usage predictably harmless. :)

On Thu, Jul 28, 2016 at 8:26 PM, Alex Otenko <[hidden email]> wrote:
What is? Reusability?

I don’t know about CompletableFuture specifically, but mutability has an immense impact on the implementation, since reuse requires knowing that the mutator repurposing the structure is the last entity looking at it in the old guise. Then there are gotchas that whoever keeps a reference to it, must also have a way of knowing which version of the thing it is looking at - like, suddenly you are not allowed to pass around CompletableFuture uncontrollably, need to devise ways to solve ABA problem - which becomes a problem due to mutability.

Alex

On 28 Jul 2016, at 16:17, Viktor Klang <[hidden email]> wrote:

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Viktor Klang


On Thu, Jul 28, 2016 at 9:35 PM, Josh Humphries <[hidden email]> wrote:
Unfortunately -- unless you create a defensive copy or use a custom subclass of CompletableFuture -- it is mutable, even as CompletionStage:

stage.toCompletableFuture().obtrudeValue(null);

Ouch! Having that method always return a new instance would've been safer, for sure.
(I always use custom CompletionStages)
 



----
Josh Humphries
Payments Engineering
Atlanta, GA  |  <a href="tel:678-400-4867" value="+16784004867" target="_blank">678-400-4867

On Thu, Jul 28, 2016 at 3:04 PM, Viktor Klang <[hidden email]> wrote:
For the CompletableFuture itself: I recommended sharing it as a CompletionStage instead, since that is not mutable.
For the value of the CompletionStage/CompletableFuture, same rules apply to most concurrent datastructures: instances made available through it needs to either be immutable, thread-safe or the usage predictably harmless. :)

On Thu, Jul 28, 2016 at 8:26 PM, Alex Otenko <[hidden email]> wrote:
What is? Reusability?

I don’t know about CompletableFuture specifically, but mutability has an immense impact on the implementation, since reuse requires knowing that the mutator repurposing the structure is the last entity looking at it in the old guise. Then there are gotchas that whoever keeps a reference to it, must also have a way of knowing which version of the thing it is looking at - like, suddenly you are not allowed to pass around CompletableFuture uncontrollably, need to devise ways to solve ABA problem - which becomes a problem due to mutability.

Alex

On 28 Jul 2016, at 16:17, Viktor Klang <[hidden email]> wrote:

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Reusing CompletableFuture

Kasper Nielsen-4

On 28 July 2016 at 21:39, Viktor Klang <[hidden email]> wrote:


On Thu, Jul 28, 2016 at 9:35 PM, Josh Humphries <[hidden email]> wrote:
Unfortunately -- unless you create a defensive copy or use a custom subclass of CompletableFuture -- it is mutable, even as CompletionStage:

stage.toCompletableFuture().obtrudeValue(null);

Ouch! Having that method always return a new instance would've been safer, for sure.
(I always use custom CompletionStages)
 



----
Josh Humphries
Payments Engineering
Atlanta, GA  |  <a href="tel:678-400-4867" value="+16784004867" target="_blank">678-400-4867

On Thu, Jul 28, 2016 at 3:04 PM, Viktor Klang <[hidden email]> wrote:
For the CompletableFuture itself: I recommended sharing it as a CompletionStage instead, since that is not mutable.
For the value of the CompletionStage/CompletableFuture, same rules apply to most concurrent datastructures: instances made available through it needs to either be immutable, thread-safe or the usage predictably harmless. :)

On Thu, Jul 28, 2016 at 8:26 PM, Alex Otenko <[hidden email]> wrote:
What is? Reusability?

I don’t know about CompletableFuture specifically, but mutability has an immense impact on the implementation, since reuse requires knowing that the mutator repurposing the structure is the last entity looking at it in the old guise. Then there are gotchas that whoever keeps a reference to it, must also have a way of knowing which version of the thing it is looking at - like, suddenly you are not allowed to pass around CompletableFuture uncontrollably, need to devise ways to solve ABA problem - which becomes a problem due to mutability.

Alex

On 28 Jul 2016, at 16:17, Viktor Klang <[hidden email]> wrote:

Isn't this a general requirement for concurrency (coordination) structures?

--
Cheers,


On Jul 28, 2016 11:57, "Alex Otenko" <[hidden email]> wrote:
An isolated fact of reuse is also not very meaningful. You need cross-board support for reuse for the bulk of memory/stateful/stateless objects referenced by CompletableFuture.

Alex

> On 24 Jul 2016, at 19:11, Pavel Rappo <[hidden email]> wrote:
>
> Hi Martin,
>
> Quite a strong statement. I don't think an isolated fact of mutability
> of an entity precludes us from reusing this entity (pool of objects?
> reusable buffers?).
>
> You're talking about obtrudeException(Throwable ex) and obtrudeValue(T
> value), right? In my example the CF was returned by an API to a user
> and this CF was completed prior to be returned.
>
> On Sun, Jul 24, 2016 at 5:19 PM, Martin Buchholz <[hidden email]> wrote:
>> Don't reuse CompletableFutures.
>> Most obviously because they're mutable.
>>
>> See also https://bugs.openjdk.java.net/browse/JDK-8161600
>>
>> On Sun, Jul 24, 2016 at 5:57 AM, Pavel Rappo <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> Is it generally safe to reuse an instance of CompletableFuture? Or am I
>>> risking
>>> with memory leaks due to dependants build up?
>>>
>>> Say, I have a method that returns a CF. In some cases it may return a CF
>>> straight away indicating that the action has been already done. Should I
>>> always
>>> create a new completed CF, or can I reuse a pre-cached one?
>>>
>>> There's a comment in the class itself, but I'm not sure I understand it
>>> enough
>>> to make a conclusion:
>>>
>>>     * ...Without precautions, CompletableFutures would be prone to
>>>     * garbage accumulation as chains of Completions build up, each
>>>     * pointing back to its sources. So we null out fields as soon as
>>>     * possible.  The screening checks needed anyway harmlessly ignore
>>>     * null arguments that may have been obtained during races with
>>>     * threads nulling out fields.  We also try to unlink non-isLive
>>>     * (fired or cancelled) Completions from stacks that might
>>>     * otherwise never be popped: Method cleanStack always unlinks non
>>>     * isLive completions from the head of stack; others may
>>>     * occasionally remain if racing with other cancellations or
>>>     * removals...
>>>
>>> Thanks,
>>> -Pavel
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> [hidden email]
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest