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()

Java ThreadLocal remove() method

Java ThreadLocal with initial value

Set value lazily on Java ThreadLocal

 
 

Using a Java ThreadLocal from within an thread pool

notion image
 

Java InheritableThreadLocal

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(); } }
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(); } }
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); } }
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); } }
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(); } }