简体   繁体   中英

My java thread code doesn't do what I want

Why does the following code have Thread-0 output 6 lines when Thread-1 only outputs 3?

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();

        }
    }
}

Output:

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

why does Thread-0 output 6 times and thread-1 3?????

Because each thread is spitting out the message based on the number of NameList.names :

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

Since names is shared between the threads, you are modifying the list in both threads. The first thread adds 3 names and must be finishing before the 2nd thread runs. Then the 2nd one adds another 3 and spits out 6.

If you want 2 threads to be updating the same list, you should protect it by using a concurrent collection or my doing the adds inside of a synchronized (names) { block. Your code is working because System.out.print() is a synchronized class so it is causes the memory to be updated between threads. If you removed the print() calls, each thread would most likely see names as being empty when they run. They also could cause the List to be corrupted or other badness.

As to why Thread-1 spits out the 3 before Thread-0 , the threads are started at the same time and it is a race condition to see which one goes first.

由于每个线程在列表中添加了3个名称,因此,在第二个线程运行之后,您添加了6个名称,并且两个线程之一将它们全部打印出来。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM