英文:
Is it necessary to add synchronized to my code?
问题
以下代码有时会在 ret.forEach(v -> System.out.println(v));
行处生成 NullPointerException 异常。
我认为我需要使用同步块或 Lock 接口来避免这个错误。
这样正确吗?
请给我一些建议。
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));
英文:
the following code sometimes generates NullPointerException Exception at ret.forEach(v -> System.out.println(v));
line.
I think I have to use synchronized block or Lock Interface to avoid this error.
Is it correct?
Please tell me some advice.
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));
答案1
得分: 2
基本上是的:你从多个线程修改一个 ArrayList
。ArrayList
不是线程安全的,因此这样做可能会导致任意数量的问题(没有单个的问题/异常会总是发生)。
在使用非线程安全的集合时,出现不应该存在的空值是可能的结果之一。
因此,从流中生成列表的最佳方式不是使用 forEach
并显式地向列表中添加元素,而是使用 map
和 collect
。
英文:
Basically yes: you modify an ArrayList
from multiple threads. ArrayList
is not thread-safe, so doing that can cause any number of issues (there is no single problem/exception that will always happen).
Null-values being present when they shouldn't be is one of the possible outcomes of using non-thread collections.
The best way to produce a list from a stream is therefore not to use forEach
and explicitly add something to a list, but to use map
and collect
.
答案2
得分: 1
这里有一些需要评论的事情:
-
在声明之前不能使用
ret
。 -
你正在并行地向
ArrayList
添加元素。ArrayList
不是线程安全的,所以不应在这里使用它。参考在Java中选择最佳并发列表。 -
最后,如果你正在使用
streams
,最好使用map
和collect
。类似于这样的方式:IntStream.range(0, 10) .parallel() .map(i -> do_watever(i)) .collect(Collectors.toList());;
英文:
There are some things here to comment:
-
You can't use
ret
before its declaration. -
You are adding elements to an
ArrayList
in parallel.ArrayList
is not threadsafe so you shouldn't use it there. Look at Choosing the best concurrency list in Java. -
Finally, if you are using
streams
, its better to use amap
and acollect
. Something similar to this:IntStream.range(0, 10) .parallel() .map(i -> do_watever(i)) .collect(Collectors.toList());;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论