Is Java 8 streams atomic?

倾然丶 夕夏残阳落幕 提交于 2019-12-18 04:23:39

问题


I read a few posts, however, I'm still confused.

I know that parallel streams will be executed in a parallel manner that will utilise the CPUs. and I believe that the sub jobs will be executed as atomic units, am I correct?

But what about regular Java 8 streams?

If i execute let's say the next line of code:

users.stream().map(user->user.getUsername()).collect(Collectors.toList()); 

Will that line be executed in a thread-safe/atomic manner as well?


回答1:


There is no such thing as general thread safety or atomicity. Atomic field updates are only atomic in respect to threads accessing the same variable, synchronized code blocks are executed atomic/thread safe in respect to threads synchronizing on the same instance only.

A stream operation in itself is a purely local operation, this holds even for parallel stream operations, as the threads participating in that operation are unrelated to any other threads. If you use functions with (non local) side effects, which is very discouraged, there are no guarantees, there's no added thread safety nor atomicity for these side effects. The only exception are the terminal operations forEach and forEachOrdered, which are intended for producing side effects and well documented regarding the behavior with multiple threads.

So the operation users.stream().map(user->user.getUsername()).collect(Collectors.toList()), assuming that the method getUsername() follows the contract and has no side effects, is not visible to any other thread at all. If you publish the returned list to other threads in a thread safe way, it will be safe, if you let it escape in an unsafe way, there will be no guarantees. If you never publish the result to other threads, the question becomes irrelevant.




回答2:


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




回答3:


The stream API defines numerous contracts for each step of the pipeline, if any of them are violated then unpredictable behavior or exception may happen.

  • Spliterator. note the late-binding, IMMUTABLE and CONCURRENT properties, which can differ for various sources.
  • the collection sources usually specify the nature of their spliterators, e.g. ConcurrentHashMap reports CONCURRENT for its views, while HashMap does not. Which means hashmap cannot handle modification by outside threads or interfering side-effects within the stream pipeline.
  • each operation in a pipeline defines which properties the user-supplied methods should have, the key concepts are non-interference, statefulness and side-effects. Compare filter and peek.
  • Collector/Collectors don't spell out their requirements quite as clearly, but the supplied functions should generally be non-interfering, side-effect-free and stateless just like intermediate ops, especially when concurrent collectors are used.

In general, if you do everything right then both parallel and sequential streams are safe to use, even on collections that do not support concurrent modification.

If you're doing things that violate these requirements then sequential streams may be a little more forgiving, but they may still fail.



来源:https://stackoverflow.com/questions/39879935/is-java-8-streams-atomic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!