아이템 84. 프로그램의 동작을 스레드 스케쥴러에 기대지 말라 운영체제 쓰레드 스케쥴러에 의존하지 마라 자바 어플리케이션의 운영체제에 대한 이식성을 낮춘다. 쓰레드를 효율적으로 사용하는 방법은 실행 가능한 스레드가 프로세서보다 너무 많지 않도록 유지하는 것. 실행 가능한 스레드를 가능한 적게 유지하는 것은 컨텍스트 스위칭 비용을 적게 가져가고, Busy Waiting 하는 쓰레드를 줄이라는 의미임. 쓰레드는 바쁜 대기(Busy Waiting)을 하면 안됨. 아무 작업도 하지 않는데 CPU만 점유하는 꼴이 됨. 쓰레드의 상태는 다음으로 나눌 수 있음. 대기 쓰레드 : Object.wait()로 대기중 / synchronized 모니터락을 얻기 위해 대기중인 쓰레드 / Thread.sleep()을 만나 대기..
아이템 81. wait(), notify()보다는 동시성 유틸리티를 애용하라. 동시성 유틸리티(Concurrent 패키지)는 세 가지 맥락을 제공함. Exeuctor Service 관련 (ExeutorService) Concurrent Collection 관련 (ConcurrentHashMap 같은 것들) 동기화 장치 관련 (Semaphour, CountdownLatch 같은 것들) Concurrent Collection 관련 여러 메서드의 원자적인 동작은 필요한 경우 default 메서드로 제공됨. (putIfAbsent) 없는 경우 외부에서 락을 이용한 동기화 필요함. (그러나 느림) 동기화 컬렉션(Collections.synchronizedMap) 대신 동시성 컬렉션(ConcurrentHashMap..
아이템 80. 스레드보다는 실행자, Task, Stream을 애용하라. 쓰레드는 작업 단위 / 실행 메커니즘을 모두 개발자가 작성해야 함. 자바는 각종 실행 메커니즘을 추상화한 ExeuctorService를 지원함. 개발자는 이것을 사용하는게 좋음. ExecutorService에는 작업 단위(Runnable, Callable)을 제출해서 사용하도록 하자. 개발자는 작업 단위(Runnable, Callable)만 선언하면 됨. 서버의 사용 환경에 맞게 적절한 ExecutorService를 사용하는 것이 중요 소규모 서버 → CachedThreadPool 대규모 서버 → FixedThreadPool 자바의 Thread는 작업 단위 + 수행 메커니즘을 모두 표현함. public static void main(..
아이템 79. 과도한 동기화는 피하라. 외계인 메서드는 클래스 외부에서 제공된 함수 객체 같은 것을 의미한다. 동기화 블록에서는 외계인 메서드, 재정의 가능한 메서드를 호출하면 안된다. 만약 호출하면 Deadlock, 안전 실패가 발생할 수 있음. 반드시 외계인 메서드, 재정의 가능한 메서드는 동기화 블록 밖에서 호출해야함. 동기화 블록을 사용할 때의 규칙 동기화 영역에서 가능한 일을 적게 한다. 다른 스레드는 동기화 영역의 락을 얻기 위해 대기할 것이다. (낭비) 동기화 영역에서 외계인 메서드를 호출하지 않는다. 외계인 메서드는 어떤 상태를 변경할지 모른다. (안전 실패, 데드락) 외계인 메서드는 얼마나 걸릴지 모른다. (낭비) 동기화에 필요한 비용은? 동기화가 초래하는 진짜 비용은 락을 얻는데 드는 ..
아이템 78. 공유 중인 가변 데이터는 동기화해 사용하라. 동기화를 처리해야할 경우, 라이브러리를 사용해라. 동기화도 되고 성능도 빠르다. 동기화를 하면 다음이 좋음. 원자적으로 실행함. 한 쓰레드의 변경사항을 다른 쓰레드가 볼 수 있도록 보장해 줌. 컴파일러의 자바 최적화 기법에 의한 코드 변경에서 안전할 수 있음. Synchronized는 다음을 보장함. 원자적 실행 보장. 한 쓰레드의 변경사항을 다른 쓰레드가 볼 수 있도록 보장해 줌. 컴파일러의 자바 최적화 기법에 의한 코드 변경에서 안전할 수 있음. volatile은 다음을 보장함. 한 쓰레드의 변경사항을 다른 쓰레드가 볼 수 있도록 보장해 줌. 컴파일러의 자바 최적화 기법에 의한 코드 변경에서 안전할 수 있음. Synchronized의 특성 블..