나는 다음의 3 가지 경우를 취함으로써이 질문을 설명하려고 노력할 것이다. CASE I를 : 나는이 같은 것을 사용하여 동기화를위한 공유 잠금을 사용했다 :동기화를 위해 공유 잠금 대신 로컬 잠금을 사용하는 것이 안전합니까?
private static final String SHARED_LOCK = "shared_lock";
private static int i = 0;
private static int j = 0;
void increment() {
synchronized (SHARED_LOCK) {
i++;
j++;
}
}
그리고 그것은 잘 작동된다.
CASE II : 여기 변경 대신 내가 이런 일을 수행하여 지역 잠금을 사용하여 생각을 공유 잠금 사용하다 한 이제 무엇을 :
private static int i = 0;
private static int j = 0;
void increment() {
final String LOCAL_LOCK = "local_lock";
synchronized (LOCAL_LOCK) {
i++;
j++;
}
}
을 그리고 그 코드는 여전히 잘 작동되었다 발견 동기화가 여전히 작동하고 있습니다.
CASE III : 나는 로컬 locl을 변경하지만 이에는 :
final String LOCAL_LOCK = new String("local_lock");
다음 동기화 멀리 갔다. 따라서 CASE II에서 로컬 잠금은 자바가 자동으로 처리하는 String 리터럴을 지원하기 때문에 동기화를 제공 할 수 있지만 CASE III에서는 매번 새로운 String을 명시 적으로 생성하므로 동기화가 발생하지 않는 것처럼 보입니다.
그래서 내 원래의 질문으로 돌아갑니다. 누구나 사례 2가 동기화를 달성하는 올바른 방법이 아니라고 생각합니까? 그렇다면 이유를 말씀해주십시오.
미리 감사드립니다. SacTiw.
그래서 여기서는 case-2가 다른 클래스에 액세스하는 다른 스레드가이 클래스와 동일한 잠금을 사용하기 시작하여 성능이 좋지 않고 디버깅이 어려울 수 있음을 의미합니다. 권리? – sactiw
Java Language Specification에서는 Java에서 리터럴 문자열 (불변)이 다른 패키지의 다른 클래스에 있으면서 같은 String 객체에 대한 참조를 나타냅니다. 그리고이 규칙은 모든 원시 객체에도 적용됩니다. 모든 원시 객체는 모두 불변입니다. 그렇다면 case-2로 진행하면 교착 상태가 발생할 경우 성능이 좋지 않고 디버깅이 어려울 수 있습니다. 그래서 우리는 동기화가 내 질문에 case-2를 통해 가능하다고 말할 수 있다고 생각하지만 사용하는 것은 전혀 권장되지 않습니다. – sactiw
물론 그렇습니다. 비공개로 액세스 할 수없는 다른 클래스의 Object를 사용하는 것 외의 것을 사용하는 것은 대개 매우 나쁜 생각입니다. 'new'를 통해 객체를 얻는다면, 당신과 당신 만의 객체라는 것을 알 수 있습니다 (당신이 그것을 유출하지 않는다면). – Cowan