2016-06-22 4 views
15

이것은 JDK의 HashMap 클래스에 대한 keySet() 메소드입니다. 저자가 필드 (keySet)를 지역 변수 ks에 할당 한 이유는 무엇입니까?로컬 변수에 인스턴스 필드를 할당

public Set<K> keySet() { 
    Set<K> ks; 
    return (ks = keySet) == null ? (keySet = new KeySet()) : ks; 
} 

위와 아래의 차이점은 무엇입니까? 스레드 보안과 관련이 있습니까?

transient volatile Set<K> keySet; 

는 지역 변수 할당을 사용하여 단 한 번 읽고, 휘발성이기 때문에이 : 당신이 abstract class AbstractMap<K,V>keySet 선언을 보면 같은

public Set<K> keySet() { 
    return (keySet == null ? (keySet = new KeySet()) : keySet; 
} 
+0

아마; 변수가 null이 아니고 해당 값을 반환하는지 확인하면서 클래스 수준 변수를 설정하려고 시도하는 것처럼 보입니다. 나는 그걸 넘어선 단서가 없다. 전체 수업을 봐야 겠어. –

+0

아마도 의도의 명확성을 위해 – alphablue

+1

http://stackoverflow.com/q/28975415/3182664 http://stackoverflow.com/q/2785964/3182664 http://stackoverflow.com/q/의 중복으로 간주 될 수 있습니다. 37776179/3182664 http://stackoverflow.com/q/32619269/3182664 및 가능성이 다른 일부 .... – Marco13

답변

6

약간의 확장하려면합니다 (Set<K> ks 즉) 비 휘발성 참조 대 휘발성 참조하여 처리 할 것 Michael의 대답은 keySet() 메서드가 null을 반환하지 않는다는 것을 보증하기 위해서입니다. 성능상의 이점을 제공하는 것 외에도 가능성이 있습니다. 이 코드 감안

:

public Set<K> keySet() { 
    return (keySet == null ? (keySet = new KeySet()) : keySet; 
} 

그것은 keySet 필드는 제 1 판독 (keySet == null) 및 제 2 판독, 그것을 사이 null로 설정 될 수 멀티 스레드 코드를 적어도 이론적으로 가능한 것 반환됩니다. 나는 코드의 나머지 부분을 보지 않았지만 잠재적으로 null이 할당 된 keySet이있는 다른 장소가 있다고 가정합니다. 이것이 야생에서 볼 수있는 문제의 결과인지 아니면 방어적인 조치인지는 저자에게 질문이됩니다.

실제 코드 : 필드가 한 번만 읽을 때

public Set<K> keySet() { 
    Set<K> ks; 
    return (ks = keySet) == null ? (keySet = new KeySet()) : ks; 
} 

...이 문제를 가지고 있지 않습니다.

+0

예. 이것은 멀티 스레드 환경에서 안전하다는 것입니다. –

+0

@msandiford 그것은 반드시 어딘가에 null로 설정되는 것은 아니며, 공유 변수에 대한 두 가지 읽기가 있기 때문에 연산을 다시 정렬 할 수 있습니다. – Eugene

8

, 당신은이 정의 된 것을 볼 수 있습니다 당신이 제공 한 다른 예에서와 같이 두 번 읽는 것보다 저렴합니다. 직접 keySet 변수를 반환한다면

또한, 모든 클라이언트 코드는

+2

읽기 휘발성 필드에 대한 답변 주셔서 감사합니다, 나는 그것에 대해 생각하지 않았습니다. 당신은 "휘발성 참조 대 비 휘발성 참조"부분을 설명해 주시겠습니까? – joohwan

+1

"휘발성 참조 대 비 휘발성 참조"라는 개념은 없습니다. – Boann

+0

@Boann 맞습니다. 감사. –

관련 문제