Rus*_*tam -1 java java-8 java-stream java-11
考虑以下代码:
public class StreamDemo {
public static void main(String[] args) {
StreamObject obj = new StreamObject();
obj.setName("mystream");
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
list.parallelStream().forEach(l -> {
obj.setId(l);
System.out.println(obj + Thread.currentThread().getName());
});
}
static public class StreamObject {
private String name;
private Integer id;
// getters, setters, toString()
}
}
Run Code Online (Sandbox Code Playgroud)
当使用 java 11 编译并运行时,它返回以下内容:
StreamObject{name='mystream', id=4}ForkJoinPool.commonPool-worker-23
StreamObject{name='mystream', id=4}main
StreamObject{name='mystream', id=4}ForkJoinPool.commonPool-worker-9
StreamObject{name='mystream', id=4}ForkJoinPool.commonPool-worker-5
StreamObject{name='mystream', id=4}ForkJoinPool.commonPool-worker-19
Run Code Online (Sandbox Code Playgroud)
但对于 java 1.8,它返回不同的结果:
StreamObject{name='mystream', id=3}main
StreamObject{name='mystream', id=5}ForkJoinPool.commonPool-worker-2
StreamObject{name='mystream', id=2}ForkJoinPool.commonPool-worker-9
StreamObject{name='mystream', id=1}ForkJoinPool.commonPool-worker-11
StreamObject{name='mystream', id=4}ForkJoinPool.commonPool-worker-4
Run Code Online (Sandbox Code Playgroud)
为什么结果不同?
这两个结果都与 Java 内存模型一致。
执行发生的一种可能顺序是:
T1 calls setId
T1 prints
T2 calls setId
T2 prints
...
T5 calls setId
T5 prints
Run Code Online (Sandbox Code Playgroud)
但是,由于您没有做任何事情来确保设置和打印以原子方式发生,因此也允许以下操作(与许多其他排序一样):
T3 calls setId
T1 calls setId
T2 calls setId
T5 calls setId
T4 calls setId
T1 prints
T1 prints
...
T5 prints
Run Code Online (Sandbox Code Playgroud)
所以,它们不同的原因是因为规范不要求它们相同;一些微妙的(或者可能不那么微妙的)实现(或环境)差异意味着它们的执行方式不同。
但是,你说,实现上的区别是什么?这不是你应该关心的事情(这听起来像是掩饰不知道的咆哮:我真的不知道)。您应该关心 Java Memory Model,因为它提供了有保证的属性。
例如,如果您想要“Java 8”行为,您可以在公共监视器上同步线程,例如obj:
list.parallelStream().forEach(l -> {
synchronized (obj) {
obj.setId(l);
System.out.println(obj + Thread.currentThread().getName());
}
});
Run Code Online (Sandbox Code Playgroud)
当然,线程仍然会以任意顺序执行;但是每个线程都会打印它设置的值。
| 归档时间: |
|
| 查看次数: |
353 次 |
| 最近记录: |