Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to stream a concurrent collection while it is modified externally?

I've a ConcurrentLinkedQueue that's accessed by multiple threads; the objects in it are immutable. In one thread, I need a snapshot of the data, which I'm doing by calling stream on it. Is it safe? I'm aware of the non-interference requirement, but it seems to be talking about modification from one of the stream operations ("stream pipelines whose source might not be concurrent should never modify the stream's data source"), not necessarily externally. Besides, the ConcurrentLinkedQueue is designed for concurrent access, so there's that.

like image 532
Abhijit Sarkar Avatar asked Jun 08 '18 07:06

Abhijit Sarkar


People also ask

Are parallel stream thread-safe?

Parallel streams provide the capability of parallel processing over collections that are not thread-safe. It is although required that one does not modify the collection during the parallel processing.

Is stream in Java thread-safe?

All access to the Stream object will be thread safe.

Does stream filter modify the original list?

That means list. stream(). filter(i -> i >= 3); does not change original list. All stream operations are non-interfering (none of them modify the data source), as long as the parameters that you give to them are non-interfering too.

Is arrays stream thread-safe?

In general no. If the Spliterator used has the CONCURRENT characteristic, then the stream is thread-safe.

What are concurrent Collections in Java?

It introduced some thread safe collections java. Java concurrent collections were introduced in version 5 and part of the java.util.concurrent package. Here java introduced some more classes that are designed for concurrent access from multiple threads.

Can I use a non-concurrent collector with parallel streams?

This means that the various implementations provided by the Collectorsclass can be used with parallel streams, even though some of those implementations might not be concurrent collectors. This also applies to any of your own non-concurrent collectors that you might implement.

What is the difference between concurrent collectors and ordinary collectors?

So, the concurrent collectors are strictly optimizations over their ordinary counterparts. And they don't come without a cost; because elements are being blasted in from many threads, concurrent collectors generally cannot preserve encounter order.

What are the problems while using collections in a multi-threaded application?

The problems which occurs while using Collections in Multi-threaded application: Most of the Collections classes objects (like ArrayList, LinkedList, HashMap etc) are non-synchronized in nature i.e. multiple threads can perform on a object at a time simultaneously. Therefore objects are not thread-safe.


1 Answers

From the documentation in link you have provided

For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification. Concurrent stream sources are those whose Spliterator reports the CONCURRENT characteristic

From documentation of the SplitIterator (its CONCURRENT characteristic)

static final int CONCURRENT

Characteristic value signifying that the element source may be safely concurrently modified (allowing additions, replacements, and/or removals) by multiple threads without external synchronization. If so, the Spliterator is expected to have a documented policy concerning the impact of modifications during traversal.

This is implementation from Collection interface stream method (which is not overridden in ConcurrentLinkedQueue)

default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
}

So as long as ConcurrentLinkedQueue uses CONCURRENT SplitIterator (which it does) I would assume you can safely iterate your ConcurrentLinkedQueue using stream().

like image 149
Michal Avatar answered Sep 30 '22 17:09

Michal