2016-10-10 1 views
4

java.util.concurrent.LinkedBlockingQueue의 메시지가 head이고 tail이 아닌 메시지가 volatile 인 이유는 무엇입니까?Java의 비 휘발성 헤드 및 테일 참조

하나의 스레드에서 head 또는 tail의 변경이 다른 스레드에서 볼 수 없으므로 이로 인해 문제가 발생합니까?

+0

흥미로운 질문입니다. 특히 그 클래스의 소스 코드를 읽기 시작하면 잠금에 관한 주석 처리 된 내용이 상당히 많이 들어 있다는 것을 알게됩니다. 및 잠금 방법 ... 사용되지 않습니다! – GhostCat

+0

잠금을 사용하여 스레드 안전을 제공합니다. –

+0

소스 코드에서 머리와 꼬리가 "비 휘발성"과 다른 "일시적"으로 표시됩니다. – Paddy

답변

8

headtailputLock 또는 takeLock으로 보호됩니다. 적절하게 동기화하는 한, 필드를 volatile으로 선언 할 필요가 없습니다.

귀하의 질문에 답변하십시오. 필드가 올바르게 동기화 된 경우 해당 필드는 volatile 일 필요는 없습니다.

용의자를 찾은 일부 코드가있는 경우 알려주십시오. 그렇지 않으면 변동될 필요가있는 이유를 찾을 수 없습니다.

+0

ReentrantLock gurantees는 모든 후속 읽기 및 쓰기가 동기화 된 블록에서와 같이 캐시가 아닌 주 메모리에서 발생하므로 다른 스레드 호출 방식은 항상 주 메모리에서 헤드를 읽습니다. – user1846749

+0

예, 맞습니다. JDK의 All Lock 구현은, 「Java ™ 언어 사양」의 17.4 섹션으로 설명되고있는 것처럼, 내장의 모니터 락이 제공하는 것과 같은 메모리 동기 시멘틱스를 실시 할 필요가 있습니다. –

0

짧은 답변 : 아니오, 가시성 문제가 발생하지 않습니다.

답변 : 차단 중입니다. 구현을 듣고 어떤 종류의 블록이 synchronized {}입니다. 변수 변경 내용은 synchronized {} 블록을 통해 전달할 수 있습니다. 명시 적으로 고정되고 다른 동기화 기술 -

0

java.util.concurrent.LinkedBlockingQueue는 머리와 꼬리 모든 비 휘발성

첫째로 참조가, volatile는 동기화 기술이 아닌 유일한 기술이다 따라서 volatile은 필수 항목은 아니지만 필드 동기화는 잠금으로 처리됩니다. John Vint의 답변에서 설명한 것처럼,이 두 개의 자물쇠가 여기에 사용됩니다.

두 번째로 참조 유형에 volatile이 사용되는 것을 볼 수 없습니다. 기본 유형에 일반적으로 사용됩니다. 자세한 설명은 another SO question을 참조하십시오. 두 답이 모두 훌륭합니다.

refer this question 또한 참조 유형을 volatile으로 선언하는 것만으로는 충분하지 않고 참조 유형에 중요한 문제가 아닌 참조 유형의 필드 값이 실제 참조가 아닌 것이므로 잘못된 결과가 발생할 수 있습니다. 모든 스레드에서 올바르게 볼 수있는 이전 버전이 아닌 참조는 다른 스레드에있는 기본 객체의 부실 필드 값을 가질 수 있습니다.