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