2014-09-05 3 views
0

일시적 객체가 이중 선택 잠금에서 안전합니까?일시적 객체는 이중 선택 잠금에서 안전합니까?

private transient java.lang.ThreadLocal __hashHistory; 
public int hashCode() { 
    if (__hashHistory == null) { 
     synchronized (this) { 
      if (__hashHistory == null) { 
       __hashHistory = new java.lang.ThreadLocal(); 
      } 
     } 
    } 

개체가 휘발성 일 필요가 있습니까?

+1

과도 변수가 이중 확인 잠금과 어떻게 관련되는지 알지 못합니다. 이중 체크 잠금이 적용된 경우 휘발성 그냥 동기화 된 블록을 구현할 것입니다 오버 헤드를 믿습니다. 그래서 답은 임의의 수식어를 사용하는 개인 변수이면 충분합니다. –

+0

내가 생각했던 이유는 우리의 이전 요새화가 이중 잠금 문제를보고하지 않았기 때문이며,이 코드는 요새화 중에 자리를 잡았다. 그래서 이전 사람이 코드를 강화하기 위해 이중 잠금 문제를 고치지 않고 어떤 이유로 든 문제를 발견했거나 시간에 문제가 있다는 것을 깨닫지 못했습니다./그 요새화가 문제가되었을 때 다시 인식되지 않았습니다 (대략 6 년 전에) 일어났다. – Zibbobz

+0

아마도 transient 키워드가 직렬화를 위해 거기에 배치되었지만 이중 방식 잠금 프로세스에는 영향을 미치지 않습니다. –

답변

3

transient은 직렬화 중에 필드를 무시해야 함을 의미합니다. 이 키워드는 스레드 잠금과 아무 관련이 없으므로 모든 것이 안전하지 않거나 안전하지 않은 상태로 유지됩니다. volatile도 도움이 될지 확실하지 않습니다.

코드에서 __hashHistory == null 인 경우 두 스레드가 동시에 synchronized 문에 접근 할 수 있습니다. 동기화 된 문장의 본문을 하나씩 전달하지만 여전히 두 개의 ThreadLocal이 생성됩니다. 이것이 더블 체크 락킹이 안티 패턴으로 간주되는 이유입니다. 바로 잡기가 매우 어렵습니다.

+1

"새로운"메모리 모델에서 '휘발성'으로 작동합니다. 코드의 유일한 문제점은 공개적으로 표시되는 객체를 동기화하는 것입니다. – biziclop

1

트랜 션트는 스레드 안전성과 아무 관련이 없습니다. 일시적인 키워드는 직렬화와 관련이 있습니다. http://en.wikibooks.org/wiki/Java_Programming/Keywords/transient

휘발성은 로컬 스레드 캐시 값이 아닌 필드의 전역 값을 읽도록합니다. 이 필드가 한 명령어에서 다음 명령어 사이에서 동일하게 유지되는지에 대해서는 어떠한 보장도하지 않습니다. 그래서 당신은 두 번 확인해야합니다.