programing

AtomicBoolean보다 Java에서 휘발성 부울을 사용하는 것이 더 나은 경우는 언제입니까?

kingscode 2021. 1. 18. 08:11
반응형

AtomicBoolean보다 Java에서 휘발성 부울을 사용하는 것이 더 나은 경우는 언제입니까?


이 질문에 이미 답변이 있습니다.

나는 SO에서 다른 휘발성 대 Atomicxxxx 질문 ( 질문 포함 )을 살펴보고 java.util.current.atomic 설명을 읽었 으며 뉘앙스에 만족하지 않습니다.

volatile boolean사용 중에서 결정하려는 경우 AtomicBooleanAtomicBoolean에서 제공하는 원자 읽기-수정-쓰기 작업 외에 실질적인 차이점이 있습니까? (예 : compareAndSet()getAndSet())

내가 가지고 있다고 가정

volatile boolean flag;

그런 다음 하나 이상의 스레드가 플래그를 설정합니다 (지우지는 않음). 플래그를 읽는 스레드가 하나 있고 설정된 경우 작업을 수행 한 다음 플래그를 지우면 volatile적절합니까?

AtomicBoolean에 대한 비용이 휘발성 부울보다 높습니까?

  • 기억 공간
  • 성능 적중 ( volatile boolean메모리 펜싱 AtomicBoolean이 필요한 것으로 보임 , 메모리 펜싱 이 필요한 것으로 보임 + java.util.current.atomic 설명에 따라 CAS 작업에 대한 약간의 잠금이 필요함)

내 직감은 AtomicBoolean을 사용하여 안전을 유지하는 것입니다.하지만 volatile boolean대신 사용할 상황이 있는지 이해하고 싶습니다 (예 : 수천 개의 인스턴스가 있고 성능이 문제인 경우).


본질적으로 모든 AtomicBoolean것은 하나 volatile boolean의 객체입니다.

개체 당 약간의 오버 헤드가 있습니다. 아마도 중요하지 않지만 캐시에 들어가는 데 더 많은 메모리가있을 수 있습니다.

사용해야하는 경우 AtomicBooleanFieldUpdater성능 오버 헤드가 상당히 많이 발생하므로 자주 사용하지 않아도 괜찮습니다 ( attachNIO에서 와 같이 ).


주요 차이점 AtomicBooleanvolatile실용적인 관점에서의 비교 - 및 - 설정 동작이 원 자성 없다는 것이다 volatile변수.

 volatile boolean b;

 void foo() {
   if( b ) {
     //Here another thread might have already changed the value of b to false
     b = false;
   }
 }

그러나 모든 동시 쓰기가 멱 등성이고 하나의 스레드에서만 읽기 때문에 문제가되지 않습니다.


여기에있는 다른 답변에 완전히 동의하는지 잘 모르겠습니다. biziclop의 대답은 옳지 만 자세한 내용을 알지 않으면 안전하다고 결론을 내릴 수 없습니다.

간단한 경우 인터리빙은 다음과 같습니다.

Thread 1 (writer)   Thread 2 (Writer)  Thread 3 (Reader)
-----------------   -----------------  -----------------
flag = true;
                                       if (flag) {
                    flag = true;
                                         flag = false;
                                         doStuff();

이 괜찮을 수 (의 두 번째 세트 flag에이 true같이 중요하지 않습니다 doStuff()여전히 아마도 일이 개 필요 어떤 스레드 볼 수 있습니다.

그러나 순서를 반대로하면 스레드 3은 다음을 수행합니다.

Thread 1 (writer)   Thread 2 (Writer)  Thread 3 (Reader)
-----------------   -----------------  -----------------
flag = true;
                                       if (flag) {
                                         doStuff();
                    flag = true;
                                         flag = false;

그러면 스레드 2의 업데이트가 손실 될 수 있습니다.

물론 Thread 2가하는 일과 마찬가지로 Thread 3에 표시되도록주의해야합니다. Thread 2가 설정해야하는 다른 상태가 있으면 여기에서도 순서가 중요합니다.

간단한 경우에는 괜찮습니다.하지만 단순한 플래그 긋기보다 복잡해지면 추론하기가 훨씬 더 어려워집니다.


여기에 좋은 정보가 많이 있습니다. 그러나 유용 할 수있는 또 다른 차이점을 추가하겠습니다. AtomicBooleans 배열을 가질 수 있지만 (내 지식으로는) 휘발성 부울 배열을 가질 수 없습니다.


그런 다음 하나 이상의 스레드가 플래그를 설정합니다 (지우지는 않음). 플래그를 읽는 스레드가 하나 있고 설정된 경우 작업을 수행 한 다음 플래그를 지우면 휘발성이 적절합니까?

예, AtomicBoolean의 특수 기능이 필요하지 않은 경우 휘발성을 사용하는 것이 좋습니다. 사실 이것은 휘발성에 대한 몇 안되는 합리적인 용도 중 하나입니다.

참조 URL : https://stackoverflow.com/questions/4876122/when-is-it-preferable-to-use-volatile-boolean-in-java-rather-than-atomicboolean

반응형