11장 : 동시성

2023. 4. 22. 14:21스터디/이펙티브 자바 스터디

728x90

아이템 78. 공유 중인 가변 데이터는 동기화해 사용하라 

- synchronizaed 는 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장

- 상태가 일관되지 않은 순간의 객체가 다른 스레드가 보지 못하게 막는 용도로만 생각

- 동기화는 배타적 실행 뿐 아니라 스레드 사이의 안정적인 통신에 꼭 필요

- volatile 선언하면 동기화를 생략해도 됨

- 배타적 수행과는 상관 없지만 항상 가장 최근에 기록된 값을 보장

- 메서드에 synchronized를 붙였으면 volatile 제거해야

- Atomic 패키지는 락 없이도 스레드 안전한 프로그래밍을 지원

- Atomic 은 원자성(배타적 실행)까지 지원 

- 가장 좋은 방법은 애초에 가변 데이터를 공유하지 않는 것

- 가변데이터는 단일 스레드에서만 사용

아이템 79. 과도한 동기화는 피하라 

- 과도한 동기화는 성능을 떨어뜨리고, 교착상태에 빠트리고, 예상치 못하는 동작을 낳음

- 응답 불가와 안전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 클라이언트에게 양도하면 안 됨

- 동기화 영역 안에서는 재정의할 수 있는 메서드는 호출하면 안 되며, 클라이언트가 남겨준 함수 객체를 호출해서도 안 됨- 열린 호출은 실패 방지 효과 외에도 동시성 효율을 크게 개선- 동기화 영역에서는 가능 한 일을 적게 해야- 동기화를 전혀 하지 말고 해당 클래스 동시에 사용해야 하는 클래스가 외부에서 알아서 동기화하게 하자- 동기화를 내부에서 수행해 스레드 안전한 클래스로 만들자 단, 클라이언트가 외부에서 객체 전체에 락을 거는 것보다 동시성을 월등히 개선할 수 있을 때만 두 번째 방법을 선택해야- 락 분할, 락 스트라이핑, 비차단 동시성 제어 등 다양한 기법으로 동시성을 높일 수 있음- 여러 스레드가 호출할 가능성이 있는 메서드가 정적 필드를 수정한다면 그 필드를 사용하기 전에 반드시 동기화해야 함


아이템 80. 스레드보다는 실행자, 태스크, 스트림을 애용하라 

- 작업 큐를 손수 만드는 일은 삼가야 하고, 스레드를 직접 다루는 것도 일반적으로 삼가야


아이템 81. wait와 notify보다는 동시성 유틸리티를 애용하라 

# 조건이 만족하지 않아도 스레드가 깨어날 수 있는 상황

1. 스레드가 notify를 호출한 다음 대기중이던 스레드가 깨어나는 사이에 다른 스레드가 락을 얻어 그 락이 보호하는 상태를 변경

2. 조건이 만족되지 않았음에도 다른 스레드가 실수로 또는 악위적으로 notify 호출

3. notifyAll을 호출해 모든 스레드 깨움

4.대기중인 스레드가 notify없이 깨어남 : 허위 각성

 

- 일반적으로는 언제나 notifyAll을 사용하는게 좋음

 


아이템 82. 스레드 안전성 수준을 문서화하라 
아이템 83. 지연 초기화는 신중히 사용하라 

- 인스턴스 생성 시의 초기화 비용은 줄지만 그 대신 지연 초기화하는 필드에 접근하는 비용은 커짐

- 대부분의 상황에서 일반적인 초기화가 지연 초기화보다 낫다

- 성능 때문에 인스턴스 필드를 지연 초기화 해야 한다면 이중 검사 관용구를 사용

- 필드가 초기화된 후로는 동기화하지 않으므로 해당 필드는 반드시 volatile로 선언


아이템 84. 프로그램의 동작을 스레드 스케줄러에 기대지 말라

- 스레드는 당장 처리해야 할 작업이 없다면 실행돼서는 안 됨.

728x90

'스터디 > 이펙티브 자바 스터디' 카테고리의 다른 글

12장 : 직렬화  (0) 2023.04.22
10장 : 예외  (0) 2023.04.21
9장 : 일반적인 프로그래밍 원칙  (0) 2023.04.15
8장 : 메서드  (0) 2023.04.06
7장 : 람다와 스트림  (0) 2023.04.06