nascent
nascent

Reputation: 117

Multithreading program output is not as expected

I wrote a small program where i am storing the thread name in class level field and also printing it.

public class ThreadClass implements Runnable {

    private String threadName = null;

    @Override
    public void run() {
        System.out.println(" thread name " + threadName);
        System.out.println(" current thread  >>>>>> "
                + Thread.currentThread().getName());
        threadName = Thread.currentThread().getName();
    }
}

I wrote a test class where i created 10 threads and started them.

public class ThreadController {
    public static void main(String[] args) {
        ThreadClass threadClass = new ThreadClass();
        Thread t1 = new Thread(threadClass, "T1");
        Thread t2 = new Thread(threadClass, "T2");
        Thread t3 = new Thread(threadClass, "T3");
        Thread t4 = new Thread(threadClass, "T4");
        Thread t5 = new Thread(threadClass, "T5");
        Thread t6 = new Thread(threadClass, "T6");
        Thread t7 = new Thread(threadClass, "T7");
        Thread t8 = new Thread(threadClass, "T8");
        Thread t9 = new Thread(threadClass, "T9");
        Thread t10 = new Thread(threadClass, "T10");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
        t9.start();
        t10.start();
    }
}

I am getting following output.

 thread name null
 thread name null
 thread name null
 current thread  >>>>>> T1
 current thread  >>>>>> T6
 current thread  >>>>>> T2
 thread name T2
 thread name T2
 thread name null
 thread name null
 thread name null
 current thread  >>>>>> T4
 current thread  >>>>>> T7
 current thread  >>>>>> T8
 current thread  >>>>>> T9
 thread name T1
 current thread  >>>>>> T5
 thread name T1
 current thread  >>>>>> T3
 current thread  >>>>>> T10

My doubt is if every thread creates a local copy of field variables then why i am not always getting thread name as null. Sorry if it sounds like a silly question but i am trying to learn threads.

Upvotes: 3

Views: 131

Answers (3)

Jayamohan
Jayamohan

Reputation: 12924

Thread will not create the local copy of the fields its accessing. In your implementation all the threads are trying to access the same field in the instance threadClass and that's why its not null always.

Change your source as below, you will get the expected behavior.

Thread t1 = new Thread(new ThreadClass(), "T1");
Thread t2 = new Thread(new ThreadClass(), "T2");
Thread t3 = new Thread(new ThreadClass(), "T3");
Thread t4 = new Thread(new ThreadClass(), "T4");
Thread t5 = new Thread(new ThreadClass(), "T5");
Thread t6 = new Thread(new ThreadClass(), "T6");
Thread t7 = new Thread(new ThreadClass(), "T7");
Thread t8 = new Thread(new ThreadClass(), "T8");
Thread t9 = new Thread(new ThreadClass(), "T9");
Thread t10 = new Thread(new ThreadClass(), "T10");

Upvotes: 3

prmottajr
prmottajr

Reputation: 1824

Although you have named your variable threadName it has nothing to do with the Thread object's name. If you use the Thread constructor method that passes a String as the Thread name you will be able to use Thread.currentThread().getName() to return this String but your threadName variable won't be changed.

If you wish to use the variable the way you wrote your code then you should use a constructor in your ThreadClass that receives a String and sets the threadName like this:

public ThreadClass(String name){
    this.threadName = name;
}

And the you can use this constructor like this:

Thread t1 = new Thread(new ThreadClass("T1"));

Beware that, if you still want to use the Thread.currentThread().getName() you will have to do as follows:

Thread t1 = new Thread(new ThreadClass("T1"),"T1-name for getName");

Cheers

Upvotes: 1

javatar
javatar

Reputation: 41

You are doing this:

System.out.println(" thread name " + threadName);

before this:

threadName = Thread.currentThread().getName();

So the output you are having is normal concerning the message: thread name null. Each thread will print thread name null once it starts.

And since you are using the same ThreadClass instance for all Threads, changing the class variable threadName in one will also be changed in others. In fact, there is only one instance of ThreadClass (and in turn one instance of threadName), and every thread is using a reference to ThreadClass.

That's why you see this statement printing all thread names:

System.out.println(" current thread  >>>>>> " + Thread.currentThread().getName());

But not this:

System.out.println(" thread name " + threadName);

Learning about how Java deals with objects and references to objects will help you a lot in using threads.

Upvotes: 0

Related Questions