if I have a Thread sensitive List I go usually like this while iterating over it:
List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
I wonder if I use list.stream() and do then some operations over the stream like filter etc., if I also have to put the list into a synchronize block or does the stream makes a copy of the list?
Thanks
if your shared object is either a read-only or immutable object, then you don't need synchronization, despite running multiple threads. The same is true with what threads are doing with an object if all the threads are only reading values then you don't require synchronization in Java.
STREAMS uses a synchronization-queueing mechanism that maximizes execution throughput. A synchronization queue is a linked list of structures. Each structure encapsulates a callback to a function attempting to access a resource.
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.
The synchronizedList() method of java. util. Collections class is used to return a synchronized (thread-safe) list backed by the specified list. In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.
Stream operations use spliterator()
method internally.
Here is the spliterator()
method from ArrayList
:
public Spliterator<E> spliterator() {
checkForComodification();
return new ArrayListSpliterator<E>(ArrayList.this, offset,
offset + this.size, this.modCount);
}
It checks for comodification, so it looks like stream()
operations have to be inside synchronized blocks in your case.
Also, spliterator()
of SynchronizedCollection
(in Collections
) has comment
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
which is analogous to the comment in iterator()
:
public Iterator<E> iterator() {
return c.iterator(); // Must be manually synched by user!
}
which shows the same: synchronization is needed around stream()
operations (at least, if iterator()
requires such a synchronization).
And the most convincing: stream()
method from SynchronizedCollection
:
public Stream<E> stream() {
return c.stream(); // Must be manually synched by user!
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With