객체 구성
스레드 안전성 확보한 컴포넌트를 안전하게 서로 연결해 사용한다면 규모 있는 컴포넌트나 프로그램을 좀 쉽게 작성할 수 있을 것
스레드 안전한 클래스 설계
스레드 안전성 확보할 때 고려사항
객체 상태는 내부 변수에 의해서 결정된다. 동기화 정책 : 값이 계속 변하는 상황에서도 값을 안전하게 사용하도록 조절하는 방법
동기화 요구사항 정리
다중 연산일 수밖에 없는 거, 즉, 단일 연산으로 만들기 위해 동기화 필요한 경우
상태 의존 연산 (state-dependent)
이런 문제를 해결하기 위해서
상태가 올바르게 바뀔 경우 기다리다가 실제 연산을 수행할 수 있다. (wait, notify)
이미 구현된 라이브러리 사용하는 편이 간단하고 안전하다 (세마포어, 블로킹 큐)
상태 소유권
객체의 상태를 정의하고자 할 때, 객체가 실제로 소유하는 데이터만 기준으로 잡아야한다.
소유권?
가비지 컬렉션 기능을 고려한다면 객체 소유권 개념을 생각하기가 어렵다. C++은 특정 메소드에 객체 인스턴스를 넘겨줄 때 (내가 아직 정확하게 알지는 못하는 개념이다.)
특정 변수에 대한 소유권을 갖고 있으면, 그 변수의 상태가 올바르게 유지되도록 조절하는 락 구조에 대한 소유권도 가진다.
소유권 분리 형태를 사용하는 경우도 있다. 컬렉션 내부 구조에 대한 소유권은 컬렉션 클래스에, 컬렉션에 추가되어 있는 개체의 소유권은 클라이언트 쪽에 컬렉션에 들어있는 객체를 사용할 때 동기화 작업을 수행해야한다.
인스턴스 한정 (aka. 한정 기법, feat. 자바 모니터 패턴)
다양한 레벨의 한정
한정된 객체는 제한된 범위를 벗어나선 안된다. 이에 개발자가 충분한 주의를 기울여야 한다.
인스턴스 한정 기법은 스레드 안전성을 확보할 수 있는 가장 쉬운 방법, 동기화 적용 방법도 마음대로 선택 가능 (여러 데이터를 여러 락을 사용해 따로 동기화 하는 등)
스레드 안전성을 확보하는 방법으로 데코레이터 패턴 활용 가능 이러한 래퍼 클래스가 스레드 안전성을 확보하게 된다.
자바 모니터 패턴
스레드 안전성 위임 (aka. 위임 기법)
이미 스레드 안전한 클래스를 조합해서 사용한다고 해도 스레드에 안전하지 않을 수 있다. 주의할 것
내부 상태 변수를 외부에 공개
공개하려는 상태에 따라 다르다.
상태 변수가 스레드 안전하고, 클래스 내부에서 해당 값에 대한 의존성이 없고, 상태 변수에 대한 어떤 연산이 잘못된 상태를 야기할 수 없는 경우 제외
스레드 안전하게 구현된 클래스에 기능 추가
필요한 기능을 구현해 추가하면서 스레드 안전성도 계속해서 유지하는 방법을 찾아야 한다.
클래스 재구성 (composition)
동기화 정책 문서화하기
문서를 남기는 건 스레드 안전성을 관리하는 가장 강력한 방법 안전성을 해치지 않도록 동기화 전략을 파악할 때 동기화 관련 개발 문서를 가장 먼저 참조해야한다. 동기화 정책을 정의하는게 중요하다. (synchronized, volatile 혹은 여러 동기화 관련 클래스 사용 등)
설계 단계에서 스레드 안전성도 함께 다루자.
이러한 동기화 기법은 외부에도 영향을 미치기 때문에 스레드 안전성을 어디까지 보장하는지 문서로 남겨야한다.
Last updated