2013-08-22 63 views
0

爲什麼下面的代碼有Thread-0輸出6行,當Thread-1只輸出3?我的java線程代碼不會做我想要的

public class NameList{ 

    private List names = new ArrayList(); 
    public synchronized void addName(String name){ 
     names.add(name); 
    } 

    public synchronized void print(){ 
     for (int i = 0; i < names.size(); i++) { 
      System.out.print(names.get(i)+" "); 
      System.out.println(Thread.currentThread().getName()); 
     } 
    } 

    public static void main(String args[]){ 

     final NameList nl = new NameList(); 
     for (int i = 0; i <2; i++) { 

      new Thread(){ 
       public void run(){ 
        nl.addName("A"); 
        nl.addName("B"); 
        nl.addName("C"); 
        nl.print(); 
       } 
      }.start(); 

     } 
    } 
} 

輸出:

A Thread-1 
B Thread-1 
C Thread-1 
A Thread-0 
B Thread-0 
C Thread-0 
A Thread-0 
B Thread-0 
C Thread-0 

回答

6

爲什麼線程0輸出6次且線程1 3 ?????

由於每個線程是基於NameList.names數吐出的消息:

// the threads share the same `NameList` 
final NameList nl = new NameList(); 
... 
nl.addName("A"); 
... 
for (int i = 0; i < names.size(); i++) { 

由於names在線程之間共享,要修改在兩個線程列表。第一個線程添加3個名字,並且必須在第二個線程運行之前完成。然後第二個添加另外3個並且吐出6.

如果你想讓2個線程更新同一個列表,你應該使用併發集合或者我在synchronized (names) {塊中添加內容來保護它。你的代碼正在工作,因爲System.out.print()是一個同步類,所以它會導致內存在線程之間更新。如果您刪除了print()調用,則每個線程很可能會在運行時看到names爲空。它們也可能導致List損壞或其他不良情況。

至於爲什麼Thread-1吐出3 Thread-0,線程都在同一時間開始,這是一個競爭條件,看看哪一個先行。

0

由於每個線程都將3個名稱添加到列表中,因此,在第二個線程運行後,您將添加6個名稱,並且兩個線程中的一個將它們全部打印出來。

相關問題