[ 11 장 : 동시성 ]
⭐ 스레드 : 여러 활동을 동시에 수행할 수 있게 해준다.
하지만, 동시성 프로그래밍은 단일 스레드 프로그래밍보다 어렵다.
잘못될 수 있는 일이 늘어나고 문제를 재현하기도 어려워지기 때문이다.
=> 동시성 프로그램을 명확하고 정확하게 만들고 잘 문서화해보자 !
synchronized
키워드public class Counter {
private int count = 0; // 원자적 읽기/쓰기 가능
public void increment() {
count++; // 원자적이지 않음
}
public int getCount() {
return count; // 원자적 읽기 가능
}
}
long
과 double
외의 변수를 읽고 쓰는 동작은 원자적(atomic)이다.
❓ 원자적이라는 것은 어떤 것인가?
- 여러 스레드가 같은 변수를 동기화 없이 수정하는 중이라도, 항상 어떤 스레드가 정상적으로 저장한 값을 온전히 읽어옴을 보장한다라는 뜻이다.
❓ 왜 `long` 과 `double` 의 변수를 읽고 쓰는 것은 원자적이지 않은가?
- `int`와 `float`는 보통 4바이트 크기이므로 대부분의 시스템에서 원자적으로 읽고 쓸 수 있다.
- `long`과 `double`은 8바이트 크기로, 일부 시스템에서는 8바이트 크기의 데이터를 원자적으로 처리할 수 없기 때문에, 이 경우 읽기와 쓰기가 원자적으로 보장되지 않는다.
=> `volatile` 을 사용하면 가능하다!
자바 언어 명세는 스레드가 필드를 읽을 때 항상 수정이 완전히 반영된 값을 얻는다고 보장하지만, 한 스레드가 저장한 값이 다른 스레드에게 보이는가는 보장하지 않는다.
공유 중인 가변 데이터를 비록 원자적
으로 읽고 쓸 수 있을지라도 동기화
에 실패하면 처참한 결과로 이어질 수 있다.