如何解决是否需要将同步添加到我的代码中?
以下代码有时在ret.forEach(v -> System.out.println(v));
行生成NullPointerException异常。
我认为我必须使用同步块或锁定接口来避免此错误。
这是对的吗?
请告诉我一些建议。
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
并非线程安全的,因此这样做可能会导致任何数量的问题(不会一直出现单个问题/异常)。
不应该存在的空值是使用非线程集合的可能结果之一。
因此,从流中生成列表的最好方法是不使用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());;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。