微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否需要将同步添加到我的代码中?

如何解决是否需要将同步添加到我的代码中?

以下代码有时在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));

解决方法

基本上是:您从多个线程修改了ArrayListArrayList并非线程安全的,因此这样做可能会导致任何数量的问题(不会一直出现单个问题/异常)。

不应该存在的空值是使用非线程集合的可能结果之一。

因此,从流中生成列表的最好方法是不使用forEach并明确地向列表中添加内容,而是使用mapcollect

,

这里有些事情要评论:

  1. ret声明前不能使用。

  2. 您正在并行地将元素添加到ArrayList中。 ArrayList不是线程安全的,因此您不应该在那里使用它。看Choosing the best concurrency list in Java

  3. 最后,如果您使用的是streams,最好使用mapcollect。与此类似:

    IntStream.range(0,10)
      .parallel()
      .map(i -> do_watever(i))
      .collect(Collectors.toList());; 
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。