synchronized 키워드는 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장함
스레드가 필드를 읽을 때 항상 수정이 완전히 반영된 값을 얻는 것을 보장하지만, 한 스레드가 저장한 값이 다른 스레드에게 보이는가는 보장하지 않음
ex) 스레드 1이 x = 100을 설정하고, 스레드 2가 그 값을 읽으면, 스레드 2는 100을 읽게 됨. 하지만 그 값이 실제 메모리에서 100으로 반영된 후에 읽을 수 있다는 보장이 없다
→ 동기화는 스레드 사이의 안정적인 통신에 꼭 필요함
스레드를 멈추고 싶다?
→ Thread.stop 사용하지 말자 : 안전하지 않아 사용이 금지됨
//잘못된 코드임!!
public class StopThread {
private static boolean 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();
}
}
→ boolean
필드를 두고 false로 초기화한 후 반복문을 돌게 만듦. 다른 스레드에서 해당 스레드를 멈추게 하고 싶은 경우에 true로 초기화하게 만들어 멈추게 하는 코드
1초 후에 stopRequested를 true로 설정하면서 정상적으로 프로그램이 종료될 것 같지만 이 프로그램은 무한루프에 빠짐
동기화를 하지 않았기 때문 → 메인 스레드가 수정한 값을 백그라운드 스레드가 언제 보게될지 보증할 수 없음
stopRequested를 true로 변경했을 때, 변경사항이 백그라운드 스레드에 즉시 보이지 않을 수 있음
동가화가 빠지면 JVM이 최적화를 위한 호이스팅을 수행할
// 원래 코드
while (!stopRequested)
i++;
// Hoisting
if (!stopRequested)
while (true)
i++;