0

为什么下面的代码只输出 3Thread-0行,却输出了 6 行Thread-1

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
4

2 回答 2

6

为什么 Thread-0 输出 6 次而 thread-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 before Thread-0,线程是同时启动的,看哪一个先走是个竞态。

于 2013-08-22T22:44:07.607 回答
0

因为每个线程都向列表中添加了 3 个名称,所以在第二个线程运行后,您添加了 6 个名称,两个线程之一将它们全部打印出来。

于 2013-08-22T22:51:14.603 回答