RFR 8169808 Stream returning methods should specify if they are late binding

Martin Buchholz martinrb at google.com
Tue Nov 22 23:14:59 UTC 2016


Hmmm.... I've finally read the Spliterator spec.  I now accept that
late-binding by definition does not apply to CONCURRENT sources.  Iteration
is in any case a little weird for concurrent collections, but I think the
fundamental principle, beyond the weak consistency guarantees, is to always
return elements as long as any are available, at least until the first time
there are none AND that fact has been returned to the user.  So existing
concurrent implementations should act in "late-binding style", because it's
the best behavior for users.  In some cases (ConcurrentLinkedQueue ?) it
may even be best to keep on returning new elements even after; e.g. if
tryAdvance fails, then a new element becomes available, another tryAdvance
may succeed.  Maybe in jdk 10.

On Mon, Nov 21, 2016 at 3:23 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:

>
> > On 21 Nov 2016, at 14:19, Martin Buchholz <martinrb at google.com> wrote:
> >
> >
> >
> > On Mon, Nov 21, 2016 at 1:06 PM, Paul Sandoz <paul.sandoz at oracle.com>
> wrote:
> >
> > > The CONCURRENT Spliterators in j.u.c. do not document late-binding,
> but probably they should, given the implementation effort we've already
> done to make it so.
> > >
> >
> > Late-binding really only applies to spliterators not reporting IMMUTABLE
> or CONCURRENT. What did you have in mind?
> >
> >
> > j.u.c. Spliterators like in ConcurrentLinkedDeque ...
> >
> > https://bugs.openjdk.java.net/browse/JDK-8169739?
> focusedCommentId=14022987&page=com.atlassian.jira.
> plugin.system.issuetabpanels:comment-tabpanel#comment-14022987
> >
> > ... have extra complexity to support the idea that they are never surely
> exhausted when created, even if the collection happens to have no elements
> at that point.  I was hoping you would have opinions on that (I gave up on
> making that change).
> >
>
> Ah, i missed that, sorry. (I believe writing an @<openjdkname> in a
> comment will notify more explicitly in email.)
>
> At the moment late-binding and CONCURRENT are mutually exclusive (see the
> full definition below).
>
> On the specification of Spliterator.CONCURRENT there is this api note:
>
> * @apiNote Most concurrent collections maintain a consistency policy
> * guaranteeing accuracy with respect to elements present at the point of
> * Spliterator construction, but possibly not reflecting subsequent
> * additions or removals.
>
> In this case i think you could specify a "consistency policy" that if
> LinkedBlockingDeque is empty on spliterator construction then the
> spliterator covers no elements and does not reflect subsequent additions or
> removals. But as you say it would be a change in current behaviour and
> unless there is a sufficient improvement it would not be worth the change.
>
>
> > We make an effort to provide this behavior, but we don't promise it to
> our users!
> >
>
> Interesting case.
>
>
> > Let's look at the definition:
> > """A late-binding Spliterator binds to the source of elements at the
> point of first traversal ..."""
> > That applies equally well to concurrent and non-concurrent spliterators!
> > Why don't we specify late-binding for those concurrent spliterators that
> in fact implement it, or abandon implementing it?
> >
>
> Here is the complete definition, which is currently focused on mutable
> non-concurrent sources:
>
> * <p><a name="binding">A Spliterator that does not report {@code
> IMMUTABLE} or
> * {@code CONCURRENT} is expected to have a documented policy concerning:
> * when the spliterator <em>binds</em> to the element source; and detection
> of
> * structural interference of the element source detected after
> binding.</a>  A
> * <em>late-binding</em> Spliterator binds to the source of elements at the
> * point of first traversal, first split, or first query for estimated size,
> * rather than at the time the Spliterator is created.  A Spliterator that
> is
> * not <em>late-binding</em> binds to the source of elements at the point of
> * construction or first invocation of any method.  Modifications made to
> the
> * source prior to binding are reflected when the Spliterator is traversed.
> * After binding a Spliterator should, on a best-effort basis, throw
> * {@link ConcurrentModificationException} if structural interference is
> * detected.  Spliterators that do this are called <em>fail-fast</em>.  The
> * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
> * Spliterator may optimize traversal and check for structural interference
> * after all elements have been traversed, rather than checking per-element
> and
> * failing immediately.
>
> Paul.
>
>
>


More information about the core-libs-dev mailing list