ThreadLocal in Java
ThreadLocal
class contains threead-local variables that are associated with only one Thread
for eample a transaction id.
Java ThreadLocal example
1) A simple ThreadLocal Java example which stores an integer value a primitive type.
public class ThreadLocalTest { public static void main(String[] args) { // Thread local variable containing a Integer ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); threadLocal.set(100); System.out.println("value = " + threadLocal.get()); threadLocal.set(200); System.out.println("value = " + threadLocal.get()); } }
Output :
value = 100 value = 200
2) ThreadLocal Java example in which each Thread sets and gets its own value.
public class ThreadLocalTest extends Thread { // Thread local variable containing a Integer private ThreadLocal<Integer> threadLocal; private Integer number = 0; public ThreadLocalTest(ThreadLocal<Integer> threadLocal, Integer number) { this.threadLocal = threadLocal; this.number = number; } public static void main(String[] args) { ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); ThreadLocalTest t1 = new ThreadLocalTest(threadLocal, 100); t1.setName("Thread 1"); t1.start(); ThreadLocalTest t2 = new ThreadLocalTest(threadLocal, 200); t2.setName("Thread 2"); t2.start(); } public void run() { System.out.println(Thread.currentThread().getName() + " setting value " + number); threadLocal.set(number); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " getting value"); System.out.println("value = " + threadLocal.get()); } }
Output :
Thread 1 setting value 100 Thread 2 setting value 200 Thread 2 getting value Thread 1 getting value value = 200 value = 100
3) ThreadLocal Java example with SimpleDateFormat.
A typical scenario where you can use ThreadLocal is when multiple threads are trying to use same SimpleDateFormat instance. Since SimpleDateFormat class is not thread-safe, each Thread must have its own copy of SimpleDateFormat instance and it should be stored in a ThreadLocal.
import java.text.SimpleDateFormat; public class ThreadLocalTest extends Thread { // SimpleDateFormat is not thread-safe, so give one to each thread private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyyMMdd HHmm"); } }; public static void main(String[] args) { ThreadLocalTest t1 = new ThreadLocalTest(); t1.setName("Thread 1"); t1.start(); ThreadLocalTest t2 = new ThreadLocalTest(); t2.setName("Thread 2"); t2.start(); ThreadLocalTest t3 = new ThreadLocalTest(); t3.setName("Thread 3"); t3.start(); ThreadLocalTest t4 = new ThreadLocalTest(); t4.setName("Thread 4"); t4.start(); ThreadLocalTest t5 = new ThreadLocalTest(); t5.setName("Thread 5"); t5.start(); } public void run() { System.out.println(Thread.currentThread().getName() + " Date Format = " + formatter.get().toPattern()); if (Thread.currentThread().getName().equalsIgnoreCase("Thread 2") || Thread.currentThread().getName().equalsIgnoreCase("Thread 4")) { formatter.set(new SimpleDateFormat("yyyyMMdd")); } else { formatter.set(new SimpleDateFormat("ddMMyyyy")); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " Date Format = " + formatter.get().toPattern()); } }
Output :
Thread 5 Date Format = yyyyMMdd HHmm Thread 3 Date Format = yyyyMMdd HHmm Thread 1 Date Format = yyyyMMdd HHmm Thread 2 Date Format = yyyyMMdd HHmm Thread 4 Date Format = yyyyMMdd HHmm Thread 5 Date Format = ddMMyyyy Thread 3 Date Format = ddMMyyyy Thread 2 Date Format = yyyyMMdd Thread 4 Date Format = yyyyMMdd Thread 1 Date Format = ddMMyyyy
Oracle Docs ThreadLocal