변경 가능한 공유 데이터에 대한 액세스를 동기화할 수 없는 경우 변수가 원자적으로 읽고 쓸 수 있더라도 결과는 심각할 수 있습니다.
스레드 동기화 문제를 고려해 보겠습니다. 스레드 동기화를 위해 Java 클래스 라이브러리는 Thread.stop 메서드를 제공하지만 이 메서드는 본질적으로 안전하지 않기 때문에 홍보할 가치가 없습니다. 다음 프로그램과 같은 폴링을 사용하는 것이 더 좋을 것입니다.
다음과 같이 코드 코드를 복사합니다 .
import java.util.concurrent.TimeUnit;
공개 클래스 StopThread {
/**
* @param 인수
*/
개인 정적 부울 stopRequested;
공개 정적 무효 메인(문자열[] 인수)
InterruptedException이 발생합니다{
스레드 backgroundThread = new Thread(new Runnable() {
@보수
공개 무효 실행() {
int i = 0;
동안(!stop요청됨){
나++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
중지요청 = true;
}
}
이 프로그램이 약 1초 동안 실행된 후 메인 스레드가 stopRequested를 true로 설정하여 백그라운드의 새 스레드가 중지된다고 생각할 수 있습니다. 실제로는 그렇지 않습니다. 왜냐하면 백그라운드 스레드는 이 변경 사항을 볼 수 없기 때문입니다. 값이 계속 반복되므로 데이터를 동기화하지 않은 결과입니다. 그럼 이 작업을 동기적으로 수행해 보겠습니다.
다음과 같이 코드 코드를 복사합니다 .
import java.util.concurrent.TimeUnit;
공개 클래스 StopThread {
/**
* @param 인수
*/
개인 정적 부울 stopRequested;
개인 정적 동기화 무효 requestStop(){
중지요청 = true;
}
개인 정적 동기화 부울 stopRequested(){
stopRequested를 반환합니다.
}
공개 정적 무효 메인(문자열[] 인수)
InterruptedException이 발생합니다{
스레드 backgroundThread = new Thread(new Runnable() {
@보수
공개 무효 실행() {
int i = 0;
동안(!stopRequested()){
나++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
요청정지();
}
}
이렇게 하면 데이터 동기화가 이루어집니다. 쓰기 메서드(requestStop)와 읽기 메서드(stopRequested)가 모두 동기화되어야 한다는 점은 주목할 가치가 있습니다. 그렇지 않으면 진정한 의미에서 여전히 동기화되지 않습니다.
또한 휘발성 변수 수정자를 사용하여 동기화 작업을 보다 간단하게 완료할 수 있습니다.
다음과 같이 코드 코드를 복사합니다 .
import java.util.concurrent.TimeUnit;
공개 클래스 StopThread {
/**
* @param 인수
*/
개인 정적 휘발성 부울 stopRequested;
공개 정적 무효 메인(문자열[] 인수)
InterruptedException이 발생합니다{
스레드 backgroundThread = new Thread(new Runnable() {
@보수
공개 무효 실행() {
int i = 0;
동안(!stop요청됨){
나++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
중지요청 = true;
}
}