Java Thread输出数据到Collection收到错误的结果

时间:2016-11-19 05:34:43

标签: java multithreading

我写了一个小程序来测试java的Thread。 问题是我无法得到我预测的结果:每次100条记录。 我得到了随机数量的记录。在我删除此行的评论后:

// System.out.println(name +“Completed。”);

我每次都有预测的100条记录。 换句话说,我添加了一个System.out.println(),一切都很完美。 那是java的bug还是我没注意到的东西?

MyThread.java

public class MyThread extends Thread {

  @Override
  public void run() {

    String name = Thread.currentThread().getName();

    for (int i = 1; i <= 10; i++) {
      if (i == 10) {
        //System.out.println(name + " Completed.");
        TestThread.al.add(name);
      }
    }

  }

}

TestThread.java

import java.util.ArrayList;

public class TestThread {

  public static ArrayList<String> al = new ArrayList<String>();

  public static void main(String[] args) throws Exception {

    ArrayList<MyThread> mt = new ArrayList<MyThread>();

    //set
    for (int i = 0; i < 100; i++) {
      mt.add(new MyThread());
      mt.get(i).setName("Worker " + (i + 1));
    }

    //start
    for (int i = 0; i < 100; i++) {
      mt.get(i).start();
    }

    //end
    for (int i = 0; i < 100; i++) {
        mt.get(i).join();
    }

    //result
    for (int i = 0; i < al.size(); i++) {
      System.out.println("Rank " + (i+1) + " : " + al.get(i));
    }

  }

}

2 个答案:

答案 0 :(得分:3)

ArrayList不是thread-safe,可能存在这样的情况:两个threads将数据写入arrayList的同一个positon,你可以使用Vector代替它是线程 - 安全。

有关thread-safehere

的更多信息

答案 1 :(得分:0)

cainiaofei已经回答了这个问题,但是想补充几点:

您的ArrayList对象 al导致问题,因为许多线程正在同时访问(读取/写入)

您需要了解以下基本要点:

每当许多线程同时访问对象时,确保您需要使用线程安全的类,如Collections.synchronizedList()(更喜欢这个)或Vector

如果您需要基本类型的线程安全性,您可以使用JDK的原子包,您可以查看here