ThreadLocal이란?
스레드의 Stack마다 정보를 따로 저장할 수 있는 공간입니다.
ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에,
특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있습니다.
내부적으로 HashTable의 구조를 갖고 있습니다.
스레드 전용 전역변수라는 느낌을 받았습니다.

사용 이유
Spring Integration을 사용하여 Message기반 이벤트 처리를 하고 있습니다.
Command가 성공적으로 Transaction Commit을 성공하였을때 AOP를 활용하여 Event 처리를 하고 있습니다.
이때 Commit을 성공한 정보를 ThreadLocal에 저장하여 Event Channel로 보낼때 사용하였습니다.
궁금하시다면 TransactionSynchronizationManager를 사용해 Transaction 이후에 Event 등록하기 를 참고해주세요
주의사항
쓰레드 풀 환경에서 ThreadLocal을 사용하는 경우 ThreadLocal 변수에 보관된 데이터의 사용이 끝나면
반드시 해당 데이터를 삭제해 주어야 합니다.
그렇지 않을 경우 재사용되는 쓰레드가 이전에 저장되있던 데이터를 사용하기 때문에 원하는대로 동작하지 않을것입니다.
코드 적용 방법
ThreadLocal은 set, get, remove 메소드가 있습니다.
Event를 감싸는 Events를 만들어서 ThreadLocal을 사용하였습니다.
여러개의 요청이 들어와 저장될 수 있기 때문에 List로 할당하였습니다.
ThreadLocal의 메서드를 사용하고 있습니다.
public class Events {
private static ThreadLocal<List<Event>> eventThreadLocal = ThreadLocal.withInitial(ArrayList::new);
private Events() {
throw new IllegalStateException("Do not Initialize.");
}
public static <T> void register(T event) {
if (event == null) {
return;
}
eventThreadLocal.get().add((Event) event);
}
public static List<Event> getEvents() {
return eventThreadLocal.get();
}
public static void clear() {
eventThreadLocal.get().clear();
}
}
이제 원하는 곳에서 Events객체를 이용해 ThreadLocal을 사용하면 됩니다!
느낀점
Thread를 사용할때는 항상 Thread-safe해야한다는 것을 정확히 모르고 있었는데
이번에 ThreadLocal을 공부하면서 Thread-safe에 대해 공부할 수 있게 되었습니다.
또한 ThreadLocal을 사용하면서 AOP, Spring Integration까지 여러가지 기능을 사용해보아서
정말 좋은 경험이였습니다.
참고
'Project > 개인프로젝트' 카테고리의 다른 글
[Error] Multi Module 적용 에러 (0) | 2023.10.19 |
---|---|
Spring Integration 적용하기 (0) | 2023.10.07 |
[Spring Integration] Direct Channel과 Executor Channel 차이 (0) | 2023.10.07 |
TransactionSynchronizationManager를 사용해 Transaction 이후에 Event 등록하기 (0) | 2023.10.06 |
ThreadLocal 초기화 에러 (0) | 2023.10.02 |
ThreadLocal이란?
스레드의 Stack마다 정보를 따로 저장할 수 있는 공간입니다.
ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에,
특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있습니다.
내부적으로 HashTable의 구조를 갖고 있습니다.
스레드 전용 전역변수라는 느낌을 받았습니다.

사용 이유
Spring Integration을 사용하여 Message기반 이벤트 처리를 하고 있습니다.
Command가 성공적으로 Transaction Commit을 성공하였을때 AOP를 활용하여 Event 처리를 하고 있습니다.
이때 Commit을 성공한 정보를 ThreadLocal에 저장하여 Event Channel로 보낼때 사용하였습니다.
궁금하시다면 TransactionSynchronizationManager를 사용해 Transaction 이후에 Event 등록하기 를 참고해주세요
주의사항
쓰레드 풀 환경에서 ThreadLocal을 사용하는 경우 ThreadLocal 변수에 보관된 데이터의 사용이 끝나면
반드시 해당 데이터를 삭제해 주어야 합니다.
그렇지 않을 경우 재사용되는 쓰레드가 이전에 저장되있던 데이터를 사용하기 때문에 원하는대로 동작하지 않을것입니다.
코드 적용 방법
ThreadLocal은 set, get, remove 메소드가 있습니다.
Event를 감싸는 Events를 만들어서 ThreadLocal을 사용하였습니다.
여러개의 요청이 들어와 저장될 수 있기 때문에 List로 할당하였습니다.
ThreadLocal의 메서드를 사용하고 있습니다.
public class Events {
private static ThreadLocal<List<Event>> eventThreadLocal = ThreadLocal.withInitial(ArrayList::new);
private Events() {
throw new IllegalStateException("Do not Initialize.");
}
public static <T> void register(T event) {
if (event == null) {
return;
}
eventThreadLocal.get().add((Event) event);
}
public static List<Event> getEvents() {
return eventThreadLocal.get();
}
public static void clear() {
eventThreadLocal.get().clear();
}
}
이제 원하는 곳에서 Events객체를 이용해 ThreadLocal을 사용하면 됩니다!
느낀점
Thread를 사용할때는 항상 Thread-safe해야한다는 것을 정확히 모르고 있었는데
이번에 ThreadLocal을 공부하면서 Thread-safe에 대해 공부할 수 있게 되었습니다.
또한 ThreadLocal을 사용하면서 AOP, Spring Integration까지 여러가지 기능을 사용해보아서
정말 좋은 경험이였습니다.
참고
'Project > 개인프로젝트' 카테고리의 다른 글
[Error] Multi Module 적용 에러 (0) | 2023.10.19 |
---|---|
Spring Integration 적용하기 (0) | 2023.10.07 |
[Spring Integration] Direct Channel과 Executor Channel 차이 (0) | 2023.10.07 |
TransactionSynchronizationManager를 사용해 Transaction 이후에 Event 등록하기 (0) | 2023.10.06 |
ThreadLocal 초기화 에러 (0) | 2023.10.02 |