启用多个子线程往主线程里声明的list加入数据,最后主线程输入list为空

public class ArrayListProblem {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
            }, "线程" + i).start();
        }
        System.out.println(list);
    }
}

//输出结果:[]

有试过在子线程中直接输出list,输出的list有值,因为arrylist线程不安全,所以会报错。

但是我以上面代码运行时,代码不报错,但是list没有值。

想问一下为什么list没有值。

 

因为 子线程在add的时候,主线程已经结束了

定义一个线程类,实现Runnable 接口,在线程类里面定义list 是规范做法。

使用多个子线程访问同一块内存数据,我觉得是你没有加线程锁导致的。子线程争先恐后的强插数据,导致数据错乱了,无法插入吧!

  public static void main(String[] args) {
    List<String> list = new ArrayList<>();

    for (int i = 0; i < 30; i++) {
      new Thread(() -> {
        list.add(UUID.randomUUID().toString());
      }, "线程" + i).start();
    }
    // 当只剩下主线程和GC线程时才允许主线程向后执行
    while (Thread.activeCount() != 2);
    System.out.println(list);
  }

有多个问题,第一个是 ArrayList 是线程不安全的(但并不是 list 为空的原因)。第二个是,如果按照原来的写法,主线程已经打印了,其他的线程才会将 UUID 存放进去。所以你需要确保除主线程和GC线程以外的线程都执行结束才打印 list 的内容。

第7行的线程中list,跟你外面定义的不是一个集合

你用内部类的写法写一遍

你把生成的UUID放在new Thread之前 做个变量  然后将这个变量放进list中

您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632

非常感谢您使用有问必答服务,为了后续更快速的帮您解决问题,现诚邀您参与有问必答体验反馈。您的建议将会运用到我们的产品优化中,希望能得到您的支持与协助!

速戳参与调研>>>https://t.csdnimg.cn/Kf0y