목차

개요


ThreadLocal은 각각의 쓰레드 별로 별도의 저장공간을 제공하는 컨테이너이다.

멀티 쓰레드 환경에서 각각의 쓰레드에게 별도의 자원을 제공함으로써 공유되는 서비스에서 별도의 자원에 접근하게끔 하여 각각의 스레드가 각각의 상태를 가질 수 있도록 도와준다.

Untitled

위 그림처럼 3개의 스레드가 각각 ThreadLocal에 자원을 요청한다면 ThreadLocal은 어떤 자원을 반환해줘야 할까?

🚀참고: ThreadLocal은 공유되는 컨테이너

위 ThreadLocal이 활용되는 환경은 해당 컨테이너를 가지고 있는 서비스가 싱글톤 객체로 공유되는 객체임을 가정한다. 그렇기에 각각의 스레드는 동일한 서비스객체에 접근을 하게 되고, 동일한 ThreadLocal이라는 자원에 접근하는 것이다.

ThreadLocal을 사용하지 않는 경우


ThreadLocal을 사용하지 않고, 서비스를 구현해보고 이를 사용해보자.

public class ServiceA {
	//사용자 인증 정보
	private Authentication authentication;
	private UserRepository userRepository;
	private final ServiceA instance = new ServiceA();

	public static ServiceA getInstance(){
		return instance;
	}

	public boolean login(LoginForm form) {
		User user = userRepository.findById(form.getId()).orElseThrow(NoSuchException::new);
	
		if(PasswordEncoder.matches(user.getPassword(), form.getPassword())){
			authentication = Authentication.of(form.getId(), form.getPassword, ...);
		}
	}

	public boolean hasPrincipal(){
		return !authentication == null;
	}
}

위 코드는 로그인 정보를 토대로 로그인을 해 인증 정보를 저장하고, 저장한 인증 정보를 활용하는 싱글톤 객체이다. 그럼 이 서비스를 2개의 사용자가 사용한다고 하면 어떤 일이 일어날까?

Untitled

  1. Thread A에서 로그인을 요청하며 로그인 정보를 전달한다.
  2. 서비스에서는 로그인 정보를 비교 후 인증정보를 저장한다.