2016-11-19 82 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