ThreadLocal 이 뭘까요?

2016. 1. 5. 13:27Java


*ThreadLocal : 
http://tutorials.jenkov.com/java-concurrency/threadlocal.html



(1) 정의 
 This class provides thread-local variables.
 These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own
 ,independently initialized copy of the variable.
 ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread ( e.g. a user ID or Transaction ID). 
 쓰레드 단위로 로컬 변수를 할당하는 기능이다.  이 기능은 ThreadLocal 클래스를 통해서 제공된다. 
 일반 변수의 수명은 특정 코드 블록 (e.g. 메서드 범위, for 블록 범위 등..) 내에서만 유효하지만,
  ThreadLocal은 쓰레드 영역에 변수를 설정 할 수 있기에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용 할 수 있게 된다.
 
(2) 사용법
 (2-1) ThreadLocal 객체 생성
             ThreadLocal<UserInfo> local = new ThreadLocal<UserInfo>();
 (2-2) ThreadLocal.set() 메서드를 이용해서 현재 쓰레드의 로컬 변수에 값을 저장한다.
             local.set(currentUser);
 (2-3) ThreadLocal.get() 메서드를 이용해서 현재 쓰레드의 로컬 변수의 값을 읽어온다.
             UserInfo userInfo = local.get();
 (2-4) ThreadLocal.remove() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 삭제한다.

(3) 동작 방식
public class Context{
     public static ThreadLocal<Date> local = new ThreadLocal<Date>();
}

     이제 Context 클래스를 사용하여 쓰레드 로컬 변수를 설정하고, 사용하는 코드를 작성한다.

     class A{
          public void a(){
               Context.local.set(new Date());
               B b = new B();
               b.b();
               Context.local.remove();
          }
     }
     class B{
          public void b(){
               Date date = Context.local.get();
               C c = new C();
               c.c();
          }
     }
     class C{
          public void c(){
               Date date = Context.local.get();
          }
     }
     
     A, B, C 세 개의 클래스가 존재하는데, A.a() 메소드를 호출하면 다음 그림과 같은 순서로 메서드가 실행 된다.
     
     - A.a() 메서드에서 현재 쓰레드의 로컬 변수에 Date 객체를 저장한다.
     - B.b() 메서드에서 현재 쓰레드의 로컬 변수에 Date 객체를 읽어와 사용한다.
     - C.c() 메서드에서  현재 쓰레드의 로컬 변수에 Date 객체를 읽어와 사용한다.
     - A.a() 메서드에서 현재 쓰레드의 로컬 변수를 삭제한다.

     여기서 중요한건 A.a()에서 생성한 Date 객체를 B.b() 메서드나, C.c() 메서드의 파라미터로 전달하지 않는다는 것이다.
    
(3) 활용

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

     이 이외에도 쓰레드 기준으로 동작하는 기능 구현시 , 유용하게 사용가능하다.

(4) 주의 사항

     쓰레드 풀 환경에서 ThreadLocal을 사용하는 경우 ThreadLocal 변수에 보관된 데이터의 사용이 끝나면 반드시!!!!! 삭제 해주어야 한다.
     그렇지 않으면, 재사용되는 쓰레드가 올바르지 않은 데이터를 참조할 수 있다.



'Java' 카테고리의 다른 글

core java 따라하기 - 2  (0) 2017.06.15
core java 따라하기 - 1  (0) 2017.06.13
JUnit5 개념 잡기  (0) 2017.06.02
java8 StringJoiner 과 String.join 활용  (0) 2016.01.05
Apache Daemon 에 대해서  (3) 2015.12.08
Runtime.addShutdownHook()  (0) 2015.09.30
Top 10 Useful, Yet paranoid Java Programming Techniques  (0) 2015.09.15
Exception  (0) 2013.08.04
Regular Expressions in Java  (0) 2013.07.30
Delegate, Event , Ramda  (0) 2013.07.04