HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📝
남득윤 학습 저장소
/
🧵
멀티쓰레드, 동시성 프로그래밍
/
🧵
Java Concurrency and Multithreding
/
Java ThreadLocal

Java ThreadLocal

Java ThreadLocal introduction

💡
The Java ThreadLocal class is capable of keeping a single value internally per thread that accesses it. That means, that if multiple threads share a Java ThreadLocal, each of them can set their own value inside the ThreadLocal without overwriting each other's values. When getting the value again, each thread will get the latest value it has set on the ThreadLocal - and not any value set by other threads.
notion image

Java ThreadLocal set() and get()

public class ThreadLocalBasicExample { public static void main(String[] args) { ThreadLocal<String> threadLocal = new ThreadLocal<>(); Thread thread1 = new Thread(()->{ threadLocal.set("Thread 1"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } String value = threadLocal.get(); System.out.println("value = " + value); }); Thread thread2 = new Thread(()->{ threadLocal.set("Thread 2"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } String value = threadLocal.get(); System.out.println("value = " + value); }); thread1.start(); thread2.start(); } }

Java ThreadLocal remove() method

public class ThreadLocalRemoveExample { public static void main(String[] args) { ThreadLocal<String> threadLocal = new ThreadLocal<>(); Thread thread1 = new Thread(()->{ threadLocal.set("Thread 1"); String value = threadLocal.get(); System.out.println("1 = " + value); threadLocal.remove(); value = threadLocal.get(); System.out.println("1 = " + value); }); Thread thread2 = new Thread(()->{ threadLocal.set("Thread 2"); String value = threadLocal.get(); System.out.println("2 = " + value); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } value = threadLocal.get(); System.out.println("2 = " + value); threadLocal.remove(); value = threadLocal.get(); System.out.println("2 = " + value); }); thread1.start(); thread2.start(); } }

Java ThreadLocal with initial value

public class ThreadLocalInitialValueExample { public static void main(String[] args) { ThreadLocal<MyObject> threadLocal1 = new ThreadLocal<>(){ @Override protected MyObject initialValue() { return new MyObject(); } }; ThreadLocal<MyObject> threadLocal2 = ThreadLocal.withInitial( () -> new MyObject() ); ThreadLocal<MyObject> threadLocal3 = ThreadLocal.withInitial(MyObject::new); } }

Set value lazily on Java ThreadLocal

public class ThreadLocalLazyInitExample { public static void main(String[] args) { ThreadLocal<String> threadLocal = new ThreadLocal<>(); String value = threadLocal.get(); if(value == null){ threadLocal.set("lazily set val"); value = threadLocal.get(); } System.out.println("value = " + value); } }
 
 

Using a Java ThreadLocal from within an thread pool

notion image
 

Java InheritableThreadLocal

public class InheritableThreadLocalBasicExample { public static void main(String[] args) { ThreadLocal<String> threadLocal = new ThreadLocal<>(); InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); Thread thread1 = new Thread(() -> { System.out.println("===== Thread 1 ====="); threadLocal.set("Thread 1 - ThreadLocal"); inheritableThreadLocal.set("Thread 1 - InheritableThreadLocal"); System.out.println(threadLocal.get()); System.out.println(inheritableThreadLocal.get()); Thread childThread = new Thread( () -> { System.out.println("===== ChildThread ====="); System.out.println(threadLocal.get()); System.out.println(inheritableThreadLocal.get()); }); childThread.start(); }); thread1.start(); Thread thread2 = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("===== Thread2 ====="); System.out.println(threadLocal.get()); System.out.println(inheritableThreadLocal.get()); }); thread2.start(); } }