멀티 프로세스 프로프래밍에서 어떤 필드에 여러 스레드로부터의 동시 접근이 이뤄져도 프로그램 실행에 문제가 없음을 뜻함.
즉 동시성 문제가 발생하지 않는 안전한 동작을 의미.
어떤 함수가 한 스레드에 호출되어 실행중일 때, 다른 스레드가 호출해도 결과가 각각 올바로 주어져야 함.
공유 자원 사용 최대한 줄이고, 각 스레드에서만 접근 가능한 저장소 사용해 동시 접근 막자.
자바의 ThreadLocal 사용
해당 공유 자원에 한 스레드만 접근할 수 있도록 세마포어, 뮤텍스와 같은 락으로 통제.
상호 배제 - 하나자 잡고있으면 다른 하나는 x.
공유 자원에 접근할 때 '원자적'으로 정의된 접근 방법 사용
스프링 빈은 대부분 싱글톤 패턴으로 생성되어 Application Context에 의해서 관리됨.
-> 모든 Controller, Service, Repository는 하나의 인스턴스만 갖고 있음.
그러면 스프링 환경은 멀티 스레드임에도 어떻게 Thread Safe를 유지할까?
스프링은 요청 들어오면 해당 요청은 각각 하나의 스레드가 맡음.
모든 스레드는 스프링 빈 공유하고 내부 멤버변수도 공유.
그럼 어떻게 문제가 없이 사용하고 있을까?
-> 객체가 상태 갖지 않는 불변객체이기 때문.
@Controller, @Service같은 곳에서 사용하는 객체들은 외부에서 주입 받아서 사용(DI), 내부적으로 멤버 변수를 통해 변화시키지 않는다.
JVM에서 각 스레드는 자신의 stack 영역(지역) 갖고있고, heap 영역(전역)은 스레드간 공유.
스프링 빈 자체는 Thread Safe하지 않음!
Thread Safe하게 만들어서 사용해야 함.