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