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
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!
}