Post

(Java) ThreadLocal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class User { }

public class ThreadLocalTest {

    public static void main(String[] args) {
        User u = new User();
        ThreadLocal threadLocal = new ThreadLocal<>();
        threadLocal.set(u);
        System.out.println(threadLocal);
        System.out.println(threadLocal.get());

        new Thread(()->{
            System.out.println(threadLocal);
            System.out.println(threadLocal.get());
        }).start();

        new Thread(()->{
            threadLocal.set(u);
            System.out.println(threadLocal);
            System.out.println(threadLocal.get());
        }).start();
    }
}
1
2
3
4
5
6
7
8
java.lang.ThreadLocal@63947c6b
User@2b193f2d

java.lang.ThreadLocal@63947c6b
null

java.lang.ThreadLocal@63947c6b
User@2b193f2d
  • threadLocal이라는 변수는 안에 컨테이너를 들고 있는데, 이컨테이너가 스레드마다 독립적으로 존재 한다!
    • threadLocal 이라는 변수 자체는 각 스레드에서 조회해도 동일한 변수임
    • 그 안의 컨테이너를 .get()으로 가져왔을 때, 각 스레드마다 호출 결과가 다르다. 두 번째 스레드가 print한거 보면 null
  • 단, 세번째 스레드 처럼 threadLocal 내 컨테이너에 같은 변수를 설정하게 되면, 컨테이너 자체는 독립적이지만 컨테이너가 가리키는 변수가 같아지므로 각 스레드에서 같은 변수에 접근하게 된다.
ThreadLocal 내부 동작?
  • 자신 thread를 key로 하여 ThreadLocalmap을 가져오는 식으로 동작함
1
2
3
4
5
6
7
8
9
10
11
12
13
public T get() {
   Thread t = Thread.currentThread();
   ThreadLocalMap map = getMap(t);
   if (map != null) {
         ThreadLocalMap.Entry e = map.getEntry(this);
         if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
         }
   }
   return setInitialValue();
}
This post is licensed under CC BY 4.0 by the author.