Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not getting expected output for threaded program

Below is the program:

import java.util.Date; 

public class ThreadLocalReplaceWithString {

    public static class MyRunnable implements Runnable {

        private String threadLocal = new String("");


        @Override
        public void run() {

           threadLocal= new Date().toString();       

           try {
                        Thread.sleep(4000); 
                  } catch (InterruptedException e) { e.printStackTrace(); }

           System.out.println(Thread.currentThread().getName()+
                               " start time = "+threadLocal);

        }
    }


    public static void main(String[] args) throws InterruptedException {
        MyRunnable myRunnable = new MyRunnable();

        Thread thread1 = new Thread(myRunnable,"Thread-1");
        Thread thread2 = new Thread(myRunnable,"Thread-2");

        thread1.start();
        Thread.sleep(1000); //Start thread-2 after 1 second.
        thread2.start();


    }

}

Outputs:

Thread-1 start time = Fri May 19 06:45:47 IST 2017
Thread-2 start time = Fri May 19 06:45:47 IST 2017

Why the two time values are the same even though the new date is instantiated everytime I start a new thread. Is it because of multi core processor?

Program taken from here

like image 229
jayendra bhatt Avatar asked Feb 28 '26 09:02

jayendra bhatt


1 Answers

When you create one Runnable and pass a reference to it into two thread objects, that means the two threads are executing the same Runnable, they are changing the same object.

The run method sleeps for 4 seconds between setting the instance variable and printing it out. The second thread starts after one second. There's plenty of time for the second thread to overwrite the instance variable with a different string. When the threads print, they're printing the same value on the same Runnable.

The point the writer of the article you link to was making was that even though the two threads used the same Runnable instance, when the value changed is in a ThreadLocal then each thread saves its own value separately. The posted code shows the inverse case using a normal instance member of the shared Runnable, in order to show by contrast why ThreadLocal is useful.

If you don't want the threads to share state, give each of them its own Runnable, or use ThreadLocal. Threadlocal is useful in cross-cutting situations for confining an object to a thread, where you want different methods executed by a thread to access that same object without explicitly passing it around. (There is a common scenario using threadlocal to store instances of the non-threadsafe class SimpleDateFormat.)

Don't reach for synchronization reflexively, lots of times the most straightforward answer is to avoid sharing.

like image 162
Nathan Hughes Avatar answered Mar 02 '26 23:03

Nathan Hughes