ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ThreadLocal 이란?
    카테고리 없음 2023. 4. 20. 09:53
    ThreadLocal 이란 무엇인가. 지금 이걸 쓰는 동안에도 잘 이해가 가지 않는다. 최범균님의 블로그중에 ThreadLocal 관한 블로그가 있는데 봐도 잘 모르겠다. 물론 쓰는법은 잘 알겠는데 어디에 써야 될지.. 개발 하다보면 언젠가는 나오겠지
    {
        int a = 10;
        ...
       // 블록 내에서 a 변수 사용 가능
    }
    // 변수 a는 위 코드 블록이 끝나면 더 이상 유효하지 않다. (즉, 수명을 다한다.)
    
    반면에 ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있게 된다. 이런 내용이 있다. 한마디로 말해서 스레드 환경에서 전역 변수는 공유가 되니 로컬변수 인거 마냥 전역변수를 쓰겠다? 이말인가? 대충 이말인거 같다. 내가 이해하기로는.. 간단하게 소스를 보자.
    public class ThreadLocalTest implements Runnable {
    
      @Data
      @AllArgsConstructor
      static class UserInfo {
        private String name;
      }
    
      private static final ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<UserInfo>() {
        @Override
        protected UserInfo initialValue() {
          return new UserInfo("wonwoo");
        }
      };
    
      @Override
      public void run() {
        System.out.println("Thread Name = " + Thread.currentThread().getName() + " default value = " + userInfoThreadLocal.get().getName());
        userInfoThreadLocal.set(new UserInfo("kevin"));
        System.out.println("Thread Name = " + Thread.currentThread().getName() + "         value = " + userInfoThreadLocal.get().getName());
      }
    
      public static void main(String[] args) throws InterruptedException {
        ThreadLocalTest obj = new ThreadLocalTest();
        for (int i = 0; i < 10; i++) {
          Thread t = new Thread(obj, "" + i);
          t.start();
        }
      }
    }
    
    이 예제가 맞는지도 잘 모르겠다.ㅠㅠ 위의 코드를 보면 ThreadLocal로 선언한 userInfoThreadLocal 변수가 있다. 여기에는 UserInfo라는 객체를 넣어두었다. 결과가 어떻게 될까? 일단 결과 부터 보자.
    Thread Name = 1 default value = wonwoo
    Thread Name = 2 default value = wonwoo
    Thread Name = 2         value = kevin
    Thread Name = 4 default value = wonwoo
    Thread Name = 5 default value = wonwoo
    Thread Name = 5         value = kevin
    Thread Name = 3 default value = wonwoo
    Thread Name = 3         value = kevin
    Thread Name = 0 default value = wonwoo
    Thread Name = 4         value = kevin
    Thread Name = 1         value = kevin
    Thread Name = 9 default value = wonwoo
    Thread Name = 8 default value = wonwoo
    Thread Name = 6 default value = wonwoo
    Thread Name = 7 default value = wonwoo
    Thread Name = 9         value = kevin
    Thread Name = 7         value = kevin
    Thread Name = 6         value = kevin
    Thread Name = 8         value = kevin
    Thread Name = 0         value = kevin
    
    여기서 보면 스레드는 뒤죽박죽이지만 값은 원하는값(?)이 나온다. default 지정했던 값 wonwoo는 default value로 다 출력이 되고 실행중 바꾼 value는 kevin으로만 다 출력이 되었다. 한마디로 로컬변수 처럼 쓸수 있다는 것인거 같다.

    ThreadLocal 사용 예

    1. 사용자 인증정보 전파 - Spring Security에서는 ThreadLocal을 이용해서 사용자 인증 정보를 전파한다.
    2. 트랜잭션 컨텍스트 전파 - 트랜잭션 매니저는 트랜잭션 컨텍스트를 전파하는 데 ThreadLocal을 사용한다.
    3. 쓰레드에 안전해야 하는 데이터 보관

    ThreadLocal 주의 사항

    쓰레드 풀 환경에서 ThreadLocal을 사용하는 경우 ThreadLocal 변수에 보관된 데이터의 사용이 끝나면 반드시 해당 데이터를 삭제해 주어야 한다. 그렇지 않을 경우 재사용되는 쓰레드가 올바르지 않은 데이터를 참조할 수 있다. 조금더 공부를 해야겠다. 언제 써야 될지도 모르니 더 걱정이다. 딱히 생각나는 부분이 없다. 이것으로 조금이나마 ThreadLocal에 대해 알아봤지만 딱 언제 써야 이게 좋을지는 잘 모르겠다. 천천히 다시 살펴봐야겠다. 참고로 ThreadLocal initialValue 은 아래와 같이 람다를 이용해서 해도 된다.
      private static final ThreadLocal<UserInfo> userInfoThreadLocal = ThreadLocal.withInitial(
        () -> new UserInfo("wonwoo")
      );
    
    참고 : http://javacan.tistory.com/entry/ThreadLocalUsage

    댓글

Designed by Tistory.