Anshul
Anshul

Reputation: 309

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

Upvotes: 0

Views: 90

Answers (2)

azzurroverde
azzurroverde

Reputation: 577

Because each thread is adding 3 names to the list, so, after the second thread has run, you have 6 names added, and one of the two threads prints them all.

Upvotes: 0

Gray
Gray

Reputation: 116938

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.

Upvotes: 6

Related Questions