0

나는 각 스레드가이 ArrayList 'X'addAll()을 사용하여 더 많은 데이터를 추가하는 여러 스레드에 전달되는 ArrayList 'X'를 가지고 있습니다. 분명히 여기에 멀티 스레딩 문제가 있습니다. 한 옵션은 코드의 addAll() 부분을 'synchronized'(또는) copyOnWriteArrayList를 사용하는 것입니다.스레드 안전성이 휘발성을 보장합니까? 이 ArrayList 예제

하지만 내 질문은이 ArrayList 'volatile'을 선언하면 같은 목적을 달성 할 수 있습니까? JVM은 이러한 읽기/쓰기 명령어를 적절하게 정렬하고 멀티 스레딩 문제를 방지합니까?

+4

아니요, 휘발성은 액세스를 동기화하지 않습니다. 즉, '동기화 된'(또는 다른 잠금)이 무엇인지에 대한 것입니다. – tkausl

+4

휘발성은 여기 당신을 도울 수 없습니다. 휘발성은 목록의 내용이 아니라 참조를 의미합니다. 'synchronized'를 사용하여 목록을 잠 그거나 각 스레드가 (가능한 경우) 자체 목록을 유지하고 처리가 끝나면 목록을 함께 결합해야합니다. –

+1

http://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#_pitfall_adding_volatiles_closer_to_the_problem_helps (시간이 있다면 전체 기사)를 읽는 것이 좋습니다. – C4stor

답변

4

이 ArrayList를 'volatile'로 선언하면 같은 목적을 달성 할 수 있습니까?

실제로는 할 수 없습니다. 당신이

volatile ArrayList list; 

를 쓸 때 이것은 list 참조 휘발성이 아닌 기본 ArrayList를한다. 그것은 또한 당신이

list.add(x); 

을 수행 할 때 당신은 단지 읽기 장벽없는 쓰기 장벽을 얻을 수 있도록 list이 읽기 ​​것을 의미한다.

참고 :이 작업으로 인해 실제로 필요한 작업은 아예 수행되지 않지만 쓰기 장벽이 없으면 다른 스레드에서이 작업이 표시되지 않을 수도 있습니다.

JVM은 이러한 읽기/쓰기 명령어를 적절하게 정렬하고 멀티 스레딩 문제를 방지합니까?

이 경우 읽기를 순서대로 지정하지만이 경우 멀티 스레딩 문제를 피하는 데 사용할 수는 없습니다. 즉, JVM이 걱정할 필요없이 원하는 것을 수행 할 것이라고 가정 할뿐 아니라 휘발성으로이 작업을 수행 할 수있는 방법이 없습니다. 비교에 의한

synchronized을 올바르게 사용할 수 있습니다. 여전히 잘못 이해할 수는 있지만 어리석은 증거는 아니지만 올바른 결과를 얻을 수있는 좋은 기회입니다.

0

아니요, 휘발성은 여기서 작동하지 않습니다. 휘발성 키워드는 모든 읽기 작업이 항상 최신의 업데이트 된 값을 얻는 지 확인합니다. 여기에서 synchronized를 사용해야합니다.