1. Multi Thread 고려사항
MultiThread를 구현하는 대표적인방법은 두가지가 있습니다.
- java.lang.Thread 클래스를 상속받아서 구현하는 방법
- java.lang.Runnable 인터페이스를 구현해서 개발하는 방법
Field Member
필드의 의미는 클래스에 변수를 정의하는 공간을 의미합니다. 하지만, 객체가 여러 스레드가 접근하는 싱글톤 객체라면 filed 상태값을 갖고 있지않고, 모든 변수를 parameter -> return 형식으로 구성해야합니다.
Synchronized
동기화 처리시에 synchronized 키워드를 사용하여 스레드 간섭을 피하고 이 키워드 기반으로 구현된 Collection도 존재합니다.
List 대신 Vector, Map 대신 HashTable을 사용할 수 있지만, API 및 성능상 문제를 가지고 있습니다.
성능문제를 어떻게 해결 할 수 있을까요?
Collections 라는 utll 클래스에서 제공되는 static 메소드를 통해 해결이 가능합니다.
다음과 같이 변경하여 해결이 가능합니다.
1 | Collections.synchronizedList() |
더 나아가서, JDK 1.7부터는 ConcurrentHashMap 구현체를 제공하여 Collections utill을 사용하는것보다 보다 좋은 성능을 내는 자료구조를 제공합니다.
- ConcurrentHashMap 예시
1 | /** |
ThreadLocal
일반 변수의 수명은 특정 코드 블록(예, 메서드 범위, for 블록 범위 등) 범위 내에서만 유효합니다. 하지만 ThreadLocal
을 사용하면 반면에 ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있습니다. Thread사이에 간섭을 없애야하는 데이터에 사용이 되야하는데 멀티 스레드 환경에서는 클래스의필드에 멤버를 추가할 수 없고 매개변수로 넘겨받아야합니다. 결론적으로 스레드 내부의 싱글톤을 사용하기위해 사용합니다.
- ThreadLocal 주의 사항
- ThreadLocal 객체를 생성한다.
- ThreadLocal.set() 메서드를 이용해서 현재 쓰레드의 로컬 변수에 값을 저장한다.
- ThreadLocal.get() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 읽어온다.
- ThreadLocal.remove() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 삭제한다.
쓰레드 풀 환경에서 ThreadLocal을 사용하는 경우 ThreadLocal 변수에 보관된 데이터의 사용이 끝나면 반드시 해당 데이터를 삭제해야하며 그렇지 않을 경우 재사용되는 쓰레드가 올바르지 않은 데이터를 참조할 수 있는 가능성이 있습니다.
- ThreadLocal 사용
- 사용자 인증정보 전파 - Spring Security에서는 ThreadLocal을 이용해서 사용자 인증 정보를 전달합니다.
- 트랜잭션 컨텍스트 - 트랜잭션 매니저는 트랜잭션 컨텍스트를 전파하는 데 ThreadLocal을 사용합니다.
- 세션 정보
- Thread Safe한 데이터 저장