It's interesting how they organised the documentation.

So it is guaranteed that the ConcurrentLinkedQueue can be modified and won't break the iterator.

But I don't see anything mentioning the reverse. Can an iterator removing items from the middle of a queue (which by definition is FIFO) break the queue?

On 13/11/2024 20:37, Sebastian Marsching wrote:
Hi Bowen,

I've been reading the source code and the Java documentation.

In the code <https://github.com/apache/cassandra/blob/8d91b469afd3fcafef7ef85c10c8acc11703ba2d/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java#L244>:

        public void signalAll()
        {
            // ...
            Iterator<RegisteredSignal> iter = queue.iterator();
            while (iter.hasNext())
            {
                RegisteredSignal signal = iter.next();
                // ...
                iter.remove();  // <--- here
            }
        }

and in the documentation <https://docs.oracle.com/javase/8/docs/api///java/util/Iterator.html#remove-->:

/> The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method./

The documentation for the Iterator interface is misleading because most implementations of this interface are not thread-safe, but the implementation provided by the ConcurrentLinkedQueue is different.

The documentation for the ConcurrentLinkedQueue.iterator() method says:

public Iterator <dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/Iterator.html><E <dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/concurrent/ConcurrentLinkedQueue.html>> iterator() Returns an iterator over the elements in this queue in proper sequence. The elements will be returned in order from first (head) to last (tail).

The returned iterator is /weakly consistent/ <dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/concurrent/package-summary.html#Weakly>.

And when following the link for “weakly consistent”, we find the following definition:

Most concurrent Collection implementations (including most Queues) also differ from the usual |java.util|conventions in that theirIterators <dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/Iterator.html>andSpliterators <dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/Spliterator.html>provide/weakly consistent/rather than fast-fail traversal:

  * they may proceed concurrently with other operations
  * they will never throw |ConcurrentModificationException|
    
<dfile:///Users/termi/Library/Application%20Support/Dash/Versioned%20DocSets/Java%20-%20DHDocsetDownloader/SE11/Java.docset/Contents/Resources/Documents/java.base/java/util/ConcurrentModificationException.html>
  * they are guaranteed to traverse elements as they existed upon
    construction exactly once, and may (but are not guaranteed to)
    reflect any modifications subsequent to construction.

So, concurrent modifications to a ConcurrentLinkedQueue should not result in undefined behavior of an iterator returned by such a queue.

-Sebastian

Reply via email to