본문 바로가기

분류 전체보기

(67)
[Effective-Java] Item 82. 스레드 안전성 수준을 문서화하라 한 메소드를 여러 스레드가 동시 호출할 때 어떻게 동작하냐는 중요하다. API 문서에 아무 언급이 없으면 클래스 사용자는 여러가지 가정을 해야한다. 가정이 틀릴 경우 동기화를 충분히 하지 못하거나 지나치게 하는 상황을 초래할 수 있고 두 경우 다 심각한 오류로 이어질 수 있다. API 문서의 synchronized 한정자 API 문서에 synchronized 한정자가 보이는 메소드는 스레드 안전하다고 100% 확신할 수 없다. 자바독이 기본 옵션에서 생성한 API 문서에는 synchronized 한정자가 포함되지 않는다. 메소드 선언에 synchronized 한정자를 선언할지는 구현 이슈일 뿐 API에 속하지 않기 떄문이다. synchronized 유무로 스레드 안전성을 알수있다는 것은 모 아니면 도라는..
[Effective-Java] Item 81. wait와 notify보다는 동시성 유틸리티를 애용하라 갖고 있던 고유 락을 해제하고, 스레드를 잠들게 하는 wait와 잠들어 있던 스레드 중 임의로 하나를 골라 깨우는 notify는 synchronized 블록이나 메소드에서 호출되어야하고, 올바르게 사용하기 까다로우니 고수준 동시성 유틸리티를 사용하자. java.util.concurrent의 고수준 유틸리티는 세 범주로 나눌 수 있다. 그 중 하나는 아이템80에서 설명했던 실행자 프레임워크다. 이 외에 두 가지가 더 있다. 동시성 컬렉션(Concurrent Collection) 동시성 컬렉션은 List, Queue, Map 같은 표준 컬렉션 인터페이스에 동시성을 가미해 구현한 고성능 컬렉션으로, 높은 동시성에 도달하기 위해 동기화를 각자의 내부에서 수행한다. 따라서 동시성 컬렉션에서 동시성을 무력화하는 건..
[Effective-Java] Item 80. 스레드보다는 실행자, 태스크, 스트림을 애용하라 병렬 작업 처리가 많아지면 스레드 개수가 증가되고 그에 따라 스레드 생성과 스케줄링으로 인해 CPU가 바빠져 메모리 사용량이 늘어나고 이는 애플리케이션 성능을 저하시킨다. 이런 갑작스런 병렬 작업 폭증이 야기하는 스레드 폭증을 막으려면 ThreadPool을 사용해야 한다. 스레드풀(ThreadPool) 작업 처리에 사용되는 스레드의 개수를 제한해 두고 작업 Queue에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다. 처리가 끝난 스레드는 다시 작업 Queue에서 새 작업을 가져와 처리한다. 그래서 작업이 폭증돼도 스레드 전체 개수가 늘지 않아 급격한 성능 저하가 없다. java.util.concurrent 패키지는 실행자 프레임워크(Executor Framework)라는 인터페이스 기반의 유연한 태스크..
[Effective-Java] Item 79. 과도한 동기화는 피하라 과도한 동기화는 성능을 떨어뜨리고, 교착 상태에 빠뜨리며 예측할 수 없는 동작을 낳는다. 응답 불가와 안전 실패를 피하려면 동기화 메소드나 동기화 블록 안에서는 제어를 절대로 클라이언트에게 양도하지 말자. 재정의할 수 있는 메소드 호출이나 클라이언트가 넘겨준 함수 객체도 호출하면 안된다는 것이다. 그 메소드가 어떤 일을 할지 모르고, 통제할 수 없어서 예외 발생, deadlock, 데이터훼손을 일으킬 수 있다. 이러한 외부에서 오는 메소드를 외계인 메소드(alian method)라고 정의했다. 아이템 18에서 사용한 ForwardingSet을 재사용해 만든 옵저버 패턴으로 구현된 코드를 보자. [옵저버 패턴 참고] 관찰자들은 addObserver, removeObserver 메소드를 호출해 구독을 신청/..