item 82) 스레드 안전성 수준을 문서화하라
멀티스레드 환경에서도 API를 안전하게 사용하게 하려면 클래스가 지원하는 스레드 안전성을 명시해야한다.
- 클라이언트의 지나치거나 부족한 동기화를 사용하는 것을 방지한다.
클래스의 스레드 안전성
1) 불변(Immutable) 상수라서 외부 동기화도 필요없다. (Integer, String ....)
2) 무조건적 스레드 안전 : 이 클래스의 인스턴스는 수정될수 있으나 내부에서 충실히 동기화하고 있으므로 별도의 외부 동기화 없이 안전하게 사용할수 있다. (ConcurrentHashMap)
3) 조건부 스레드 안전 : 클래스의 일부 메서드는 동시에 사용하려면 외부 동기화가 필요하다.
Collections.synchronized 래퍼 메서드가 반환한 컬렉션들.
4) 스레드 안전하지 않음 : 동시에 사용하려면 외부 동기화 메커니즘으로 감싸야한다. ex) Arraylist, HashMap
5) 스레드 적대적 : 외부 동기화로 감싸더라도 멀티스레드 환경에서 안전하지 않다. (정적 데이터를 아무 동기화 없이 수정한다.)
고의적으로 이런 클래스를 만들지는 않겟지만, 적대적으로 밝혀진다면 재배포하거나 deprecated 시켜야한다.
- @Immutable, @ThreadSafe, @NotThreadSafe 어노테이션을 붙이자.
- 특히 조건부 스레드 안전한 클래스를 문서화할떄 주의해야한다. 어느 경우에 추가적으로 외부 동기화가 필요한지(락이 필요한지) 예외를 명시해야한다.
- 보통 클래스 단위로 스레드 안전성을 주석으로 기재하지만 , 독특한 메소드의 경우 해당 메서드의 주석에 스레드 안전성을 기재한다.
- 락 필드는 반드시 final로 만든다. 락이 중간에 바뀔 경우 끔찍한 일들이 생길수 있다.