2013-08-22 30 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个名称,并且两个线程中的一个将它们全部打印出来。

相关问题