2016-11-19 65 views
0

我写了一个测试java线程的小程序。 问题是,我无法得到我预测的结果:每次记录100条记录。 我得到了随机数量的记录。并删除该行的注释后:Java线程输出数据到收集得到错误结果

//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)); 
    } 

    } 

} 
+0

我得到所有100条带有注释行和没有注释行的记录,唯一不同的是,当您取消注释行时,顺序是随机的。 – dkb

+0

在使用Vector之后,我得到了100条记录和随机顺序,有或没有该行。那么线程测试就成功了。 :) – Frank

回答

3

ArrayList中不thread-safe,可能存在的情况:两个threads写数据到ArrayList同样positon,你可以使用Vector,因为它是线程安全的。

,了解更多有关thread-safehere

+0

谢谢。使用Vector之后,我每次获得100条记录。 – Frank

0

cainiaofei已经回答了这个问题,但希望增加几个点:

ArrayList对象al原因造成的问题,因为它是被访问(读取/写)由多个线程并发

您需要了解以下基本点:

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

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

+0

谢谢。现在我更了解同步方法。 – Frank