peaches-book-study / effective-java

이펙티브 자바 3/E
0 stars 2 forks source link

Item : 78. 공유 중인 가변 데이터는 동기화해 사용하라 #72

Open heon118 opened 1 month ago

heon118 commented 1 month ago

Chapter : 11. 동시성

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

Assignee : heon118


🍑 서론

동기화의 용도

1. 배타적 실행

2. 스레드간 통신

예시

기본형 타입이 원자적인 이유
i) 4바이트 이하의 기본형 타입 : 하나의 명령어로 처리되기 때문에, 한 스레드로만 처리된다.
ii) 8바이트의 기본형 타입 : 여러 스레드가 개입될 여지가 생겨 원자적이라 할 수 없다.

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

🍑 본론

동기화에서 발생할 수 있는 문제와 해결

Thread.stop 메소드는 사용하지 말자.

문제점

해결방법(flag polling)

코드 예시

동기화를 통해 해결
public class StopThread {
    private static boolean stopRequested;
    private static synchronized void requestStop() { // true로 설정하는 쓰기 연산을 수행
        stopRequested = true;
    }
    private static synchronized boolean stopRequested() { // flag의 현재 값을 반환하는 읽기 연산을 수행
        return stopRequested;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(() -> {
            int i = 0;
            while (!stopRequested())
                i++;
        });
        backgroundThread.start();

        TimeUnit.SECONDS.sleep(1);
        requestStop();
    }
}
volatile 사용

🍑 결론

가장 좋은 방법은 가변 데이터를 공유하지 않는 것이다.
불변 데이터만 공유하거나 아무것도 공유하지 말자.
가변 데이터는 단일 스레드에서만 쓰도록 하자
한 스레드가 데이터를 다 수정한 후 다른 스레드에 공유할 때는 해당 객체에서 공유하는 부분만 동기화해도 된다. 그러면 그 객체를 다시 수정할 일이 생기기 전까지 다른 스레드들은 동기화 없이 자유롭게 값을 읽어나갈 수 있다.
이런 객체를 effectively immutable(사실상 불변) 이라 하고 다른 스레드에 이런 객체를 건네는 행위를 safe publication(안전 발행)이라고 한다.
객체를 안전하게 발행하는 방법은 클래스 초기화 과정에서 객체를 정적, volatile, final, 혹은 보통의 락을 통해 접근하는 필드에 저장해도 된다. 동시성 컬렉션(아이템 81)에 저장하는 방법도 있다.

Referenced by