Saturday, 26 August 2017

What is Thread Local?


Hello Friends,
Today I am trying to discuss about Thread Local variable of java. You can comment your question and doubt in the blog, I will try to resolve your doubt in my next blog.


What is Thread Local?

 As name suggest Thread local variable is available locally only for a thread or in other word we can say that Thread Local variable is define in a thread scope only.
Other Thread cannot access or modify the value of Thread Local variables.
See below java code:-
public class Test {
      public static void main(String... args) {
            TestThreadLocal threadLocal = new Test().new TestThreadLocal();
            Thread threadOne = new Thread(threadLocal);
            Thread threadTwo = new Thread(threadLocal);           threadOne.start();
            threadTwo.start();

      }

      class TestThreadLocal implements Runnable {

            private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();;

            @Override
            public void run() {
                  System.out.println(threadLocal.get());
                  threadLocal.set(10);
                  System.out.println(threadLocal.get());
                  try {
                        Thread.sleep(1000);
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  }
            }
      }
}

Output of above code is: -
null
null
10
10
Here you can see that second thread can’t get the value of Thread Local variable which is set by previous thread. As you can see in above we first get the value of Thread Local variable before setting new value and every time it is null so value assigned by previous thread is not visible to next thread.

In above code let’s use a simple Integer instead of Thread Local variable and synchronized it:-
public class Test {
      public static void main(String... args) {
            TestThreadLocal threadLocal = new Test().new TestThreadLocal();
            Thread threadOne = new Thread(threadLocal);
            Thread threadTwo = new Thread(threadLocal);
            threadOne.start();
            threadTwo.start();

      }

      class TestThreadLocal implements Runnable {

            private Integer value = new Integer(10);

            @Override
            public void run() {
                  synchronized (value) {
                        System.out.println(value);
                        value = 20;
                        System.out.println(value);
                  }
                  try {
                        Thread.sleep(1000);
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  }
            }
      }
}
Output of above code:-
10
20
20
20
Here you can see that second thread can see the value assigned by previous value. As you can see that initial value is 10 which updated to 20 by first executed thread and then second thread get 20 so it is visible to second thread but if we use Thread Local variable as first example than second executing thread will not be able to see the value assigned by previously executed thread.
Let’s do some more analysis:
See below code:-

import java.util.concurrent.atomic.AtomicInteger;

public class Test {
      public static void main(String... args) {
            TestThreadLocal threadLocal = new Test().new TestThreadLocal();
            Thread threadOne = new Thread(threadLocal);
            Thread threadTwo = new Thread(threadLocal);
            threadOne.start();
            threadTwo.start();

      }

      class TestThreadLocal implements Runnable {

            private AtomicInteger value = new AtomicInteger(10);
            private ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();

            @Override
            public void run() {
                  synchronized (threadLocalValue) {
                        System.out.println("Previous value of threadLocal variable:: "+threadLocalValue.get());
                        threadLocalValue.set(10);
                        System.out.println("Updated value of threadLocal variable:: "+threadLocalValue.get());
                        System.out.println("Value:: "+value.incrementAndGet());
                  }
                  try {
                        Thread.sleep(1000);
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  }
            }
      }
}

Output of above code:-
Previous value of threadLocal variable:: null
Updated value of threadLocal variable:: 10
Value:: 11
Previous value of threadLocal variable:: null
Updated value of threadLocal variable:: 10
Value:: 12

Here you can see that we are doing some more R&D by synchronizing the Thread Local variable (which is not required) and using AtomicInteger, if we analyze the output than you will find the Thread local variable is still not visible to another thread as defined and the value of atomic integer is visible to second thread.
Good point to remember is that Thread local variable is globally available with in thread, so no need to pass the variable from methods, it can be accessed from any method.

1 comment: