是否有必要在我的代码中添加 synchronized?
Is it necessary to add synchronized to my code?
以下代码有时会在 ret.forEach(v -> System.out.println(v));
行生成 NullPointerException 异常。
我想我必须使用 synchronized block 或 Lock Interface 来避免这个错误。
这是正确的吗?
请告诉我一些建议。
List<Integer> ret = new ArrayList<>();
IntStream.range(0, 10).parallel().forEach(i -> {
if (i % 2 == 0) {
try {
System.out.println("stop" + i);
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ret.add(i);
});
ret.forEach(v -> System.out.println(v));
基本上是:您从多个线程修改 ArrayList
。 ArrayList
不是 thread-safe,所以这样做会导致 任何数量的 问题(没有一个 problem/exception 会一直发生)。
Null-values 在不应该出现的时候出现是使用 non-thread 集合的可能结果之一。
因此,从流中生成列表的最佳方法不是使用 forEach
并显式向列表中添加内容,而是使用 map
和 collect
。
这里有些东西要评论:
声明前不能使用ret
。
您正在向 ArrayList
并行添加元素。 ArrayList
不是线程安全的,所以你不应该在那里使用它。看看Choosing the best concurrency list in Java.
最后,如果你使用streams
,最好使用map
和collect
。类似于此:
IntStream.range(0, 10)
.parallel()
.map(i -> do_watever(i))
.collect(Collectors.toList());;
以下代码有时会在 ret.forEach(v -> System.out.println(v));
行生成 NullPointerException 异常。
我想我必须使用 synchronized block 或 Lock Interface 来避免这个错误。
这是正确的吗?
请告诉我一些建议。
List<Integer> ret = new ArrayList<>();
IntStream.range(0, 10).parallel().forEach(i -> {
if (i % 2 == 0) {
try {
System.out.println("stop" + i);
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ret.add(i);
});
ret.forEach(v -> System.out.println(v));
基本上是:您从多个线程修改 ArrayList
。 ArrayList
不是 thread-safe,所以这样做会导致 任何数量的 问题(没有一个 problem/exception 会一直发生)。
Null-values 在不应该出现的时候出现是使用 non-thread 集合的可能结果之一。
因此,从流中生成列表的最佳方法不是使用 forEach
并显式向列表中添加内容,而是使用 map
和 collect
。
这里有些东西要评论:
声明前不能使用
ret
。您正在向
ArrayList
并行添加元素。ArrayList
不是线程安全的,所以你不应该在那里使用它。看看Choosing the best concurrency list in Java.最后,如果你使用
streams
,最好使用map
和collect
。类似于此:IntStream.range(0, 10) .parallel() .map(i -> do_watever(i)) .collect(Collectors.toList());;