[JAVA] 스레드 로컬

권재현·2024년 11월 8일

JAVA

목록 보기
10/11

들어가며..

  • 여러 스레드가 같은 인스턴스의 필드에 접근하면 최초 스레드가 보관한 데이터는 다른 스레드에 의해 덮어씌워질 수 있다.



  • 위의 과정처럼 서로 다른 스레드가 인스턴스 필드를 동시에 사용했을 경우 의도하지 않는 동작을 하는 문제점이 발생한다. 이러한 문제를 해결하고자 스레드 로컬을 고려할 수 있다.

    정의

  • 스레드 로컬이란 각 스레드마다 별도의 내부 저장소를 제공하여 해당 스레드만 접근할 수 있는 특별한 저장소이다.

  • 위의 예시에서 Thread A에게는 A만의 저장소를 ,B에게는 B만의 저장소를 제공함으로써 의도치 않은 동작을 방할 수 있다.

    사용법

TheadLocal<String> threadLocal = new ThreadLocal<>();
  threadLocal.set("userA"); //스레드 로컬 저장
  threadLocal.get(); //스레드 로컬 조회
  threadLocal.remove(); //스레드 로컬 제거

단점

  • 스레드 로컬을 모두 사용하고나면 반드시 remove()등의 메소드를 호출해서 스레드 로컬에 저장된 데이터를 제거해야한다. WAS처럼 스레드 풀을 사용하는 경우, 스레드 로컬에 데이터가 저장된채 스레드 풀에 반환되고, 이후 스레드 풀에 동일한 스레드가 꺼내져서 사용되면 이전에 저장된 스레디 로컬의 데이터가 반환되어 의도치 못한 동작을 발생 시킬 수 있기 때문이다.

  • 다음과 같은 케이스를 참고해볼 수 있다.


  • 또한 해당 저장소는 해당 스레드만 접근이 가능한 곳이므로(가비지 컬렉터가 회수할 수 없다!) 스레드가 반환되는 즉시 스레드 로컬이 제거되어야한다. 스레드 로컬을 제거하지 않은채 지속적으로 스레드를 생성/반환을 반복하면 메모리 누수가 발생할 수 있다.

VS synchronization?

  • 단순히 수치적인 성능혹은 작업속도만 따지고 보자면 ThreadLocal이 우위에 있을 수 있다. 다만 이것도 멀티 스레드가 원활히 돌아갈 정도로 하드웨어 성능이 받쳐주어야하고 스레드 반환시 스레드 로컬 데이터가 제때 삭제된다는 전제하에서만 가능하다.
  • 서버 애플리케이션에서 모든 스레드에 공유되며 동기화되어야할 데이터가 있는 사례라면 synchronization을 써야 하므로 성능보단 사용하고자 하는 경우가 어떠냐에 따라 스레드 로컬이 유리할수도 synchronization과 같은 방법이 유리할 수 도 있다.

출처

https://f-lab.kr/insight/understanding-and-utilizing-threadlocal https://yeonbot.github.io/java/ThreadLocal/
https://stackoverflow.com/questions/36157990/when-should-one-prefer-threadlocal-over-synchronization-apart-from-for-the-perf

profile
여전히 헤매이고 있습니다.

0개의 댓글