JAVA 다 중 스 레 드. - 부 울 상수 동기 화하 지 마 세 요.
동기 코드 작성 방법 은 다음 과 같 습 니 다.
코드 1:
Object obj = new Object();
...
synchronized(obj) {
//TODO:
}
JAVA 의 다 중 스 레 드 는 항상 함정 으로 가득 차 있 습 니 다. 만약 에 우리 가 Boolean 을 동기 화 대상 으로 한다 면 다음 과 같은 두 가지 상황 이 발생 할 수 있 습 니 다.
1. 한 대상 에 자 물 쇠 를 채 우 고 실제 동기 화 하 는 것 은 서로 다른 대상 이 라 고 생각 합 니 다.
코드 2:
private volatile Boolean isTrue = false;
publich void aMethod() {
...
synchronized(isTrue) {
isTrue = !isTrue;
//TODO:
isTrue = !isTrue;
}
...
}
위의 코드 를 보면 문제 가 없습니다. synchronized (isTrue) 를 사용 하여 같은 시간 에 하나의 스 레 드 만 임계 자원 에 접근 할 수 있 기 때 문 입 니 다. 그러나 사실은 그렇지 않 습 니 다.false 와 true 라 는 두 상수 가 서로 다른 대상 에 대응 하기 때문이다.isTrue 가 변화 할 때 서로 다른 스 레 드 가 서로 다른 대상 을 동기 화 할 수 있 습 니 다.JAVA 의 자동 포장 은 false 를 Boolean. FALSE 로, true 를 Boolean. TRUE 로 변경 합 니 다.이상 의 상황 을 기록 하 는 테스트 코드 는 다음 과 같 습 니 다.
코드 3:
public class BooleanTest {
private volatile Boolean isTrue = Boolean.FALSE; // false
public void aMethod() {
for(int i=0;i<10;i++) {
Thread t = new Thread() {
public void run() {
synchronized(isTrue) {
isTrue = !isTrue;
System.out.println(Thread.currentThread().getName() + " - isTrue=" + isTrue);
try{
Double ran = 1000 * Math.random();
Thread.sleep(ran.intValue());
}catch(InterruptedException e) {}
if(!isTrue) System.out.println(Thread.currentThread().getName() + " - Oh, No!");
isTrue = !isTrue;
}
}
};
t.start();
}
}
public static void main(String... args) {
BooleanTest bt = new BooleanTest();
bt.aMethod();
}
}
상기 코드 를 실행 하면 "- Oh, No!"를 자주 볼 수 있 습 니 다. 서로 다른 스 레 드 가 synchronized 코드 블록 에 동시에 들 어 가 는 것 을 의미 합 니 다.
2. 동기 화 된 것 이 서로 다른 대상 이 라 고 생각 하고 실제 적 으로 대상 이다.
때때로 우 리 는 여러 대상 에서 동기 화 를 원 할 수도 있다. 만약 에 Boolean 을 동기 화 대상 으로 사용한다 면 원래 관계 가 없어 야 할 두 동기 블록 이 같은 대상 의 자 물 쇠 를 사용 하 게 될 수도 있다.예 는 다음 과 같다.
코드 4:
private volatile Boolean aBoolean = Boolean.FALSE;
private volatile Boolean anotherBoolean = false;
public void aMethod() {
...
synchronized(aBoolean) {
//TODO: 1
}
...
}
public void anotherMethod() {
...
synchronized(anotherBoolean) {
//TODO: 2
}
...
}
원래 aMethod 와 anotherMethod 가 각각 두 조 의 관계 가 없 는 스 레 드 로 호출 된다 고 가정 합 니 다.그러나 Boolean. FALSE 와 false 가 같은 대상 을 가리 키 기 때문에 임계 자원 2 에 대한 접근 이 임계 자원 1 에 의 해 막 힐 수 있 습 니 다 (반대로 도 마찬가지 입 니 다).
상기 두 가지 상황 은 동기 블록 을 사용 할 때 가능 한 한 Boolean 대상 을 동기 화 대상 으로 사용 하지 않 아 도 된다 는 것 을 설명 한다. 그렇지 않 으 면 예상 치 못 한 문제 가 발생 하거나 향후 코드 수정 에 함정 을 초래 할 수 있다.
이 를 통 해 알 수 있 듯 이 상수 에 대한 동기 화 는 모두 위험 하 다.부 울 린 을 동기 화 하려 면 new 연산 자 를 사용 하여 부 울 린 대상 을 만들어 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.