> On 22 Nov 2016, at 15:14, Martin Buchholz <marti...@google.com> wrote:
> 
> 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.

Agreed.


> 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.
> 

I suppose there is a solution in such cases, but you might not like it: get new 
instance of the spliterator or iterator.

Spliterator.tryAdvance is specified to give such wiggle room, perhaps 
unintentionally or foreseeing such a use case? I suspect the former, testing 
wise we have interpreted returning false as always returning false on 
subsequent calls, and so do the Iterators wrapping Spliterators.

Paul.

> On Mon, Nov 21, 2016 at 3:23 PM, Paul Sandoz <paul.san...@oracle.com 
> <mailto:paul.san...@oracle.com>> wrote:
> 
> > On 21 Nov 2016, at 14:19, Martin Buchholz <marti...@google.com 
> > <mailto:marti...@google.com>> wrote:
> >
> >
> >
> > On Mon, Nov 21, 2016 at 1:06 PM, Paul Sandoz <paul.san...@oracle.com 
> > <mailto:paul.san...@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
> >  
> > <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.
> 
> 
> 

Reply via email to