2015-01-26 10 views
9

Tytuł wątek powinien być self-explnatory ... Jestem nieco mylić między specyfikacją poniżej Methos z AtomicBoolean klasy:Różnica między getAndSet i compareAndSet w AtomicBoolean

  • java.util.concurrent.atomic.AtomicBoolean#compareAndSet
  • java.util.concurrent.atomic.AtomicBoolean#getAndSet

Moja assecja jest taka, że ​​oba będą powodować takie samo zachowanie, gdy będą używane jako klauzula boolowska w stanie if:

public class Test { 
    private AtomicBoolean flag = AtomicBoolean(false); 

    public void processSomeAction() { 
    if (flag.getAndSet(false)) { // Shouldn't this be similar to flag.compareAndSet(false) 
     // process some action 
    } 
    } 
    //... 
    private void internalMutatorMethod() { 
    // do some staff then update the atomic flag 
    flas.set(true); 
    } 
} 

Zakładając, że chcę odzyskać aktualną wartość flagi i zaktualizować ją automatycznie, czy obie metody nie powinny generować tego samego zachowania?

Byłbym wdzięczny za wszelkie wyjaśnienia dotyczące tego, jak i kiedy używać każdego z nich, jeśli brakuje wewnętrznych różnic.

+1

compareAndSet ma dwa argumenty. Javadoc wskazuje, że jest zupełnie inny niż getAndSet. - Możesz napisać połączenie do compareAndSet, które robi to samo co getAndSet, ale nie jest to warte pytania. – laune

Odpowiedz

10

The documentation jest całkiem jasne.

  • getAndSet -> "Atomowo ustawia na podaną wartość i zwraca poprzednią wartość."
  • compareAndSet -> "Atomowa ustawia wartość na podaną zaktualizowaną wartość, jeśli aktualna wartość == oczekiwana wartość."

Nic dziwnego, że compareAndSet przyjmuje dwa argumenty.

W Twoim konkretnym przypadku:

  • if (flag.getAndSet(false)) będzie ustawiony flag do false tylko jeśli jego poprzednia wartość była true
  • To byłoby odpowiednikiem if (flag.compareAndSet(true, false))
+0

Tak, dokumentacja jest dość przejrzysta, jak sugerujesz i widzę różnicę ogólnie mówiąc ... ale staram się zobaczyć różnicę w oparciu o fragment kodu, który napisałem w głównym wątku. Czy to ma jakieś znaczenie? – tmarwen

+0

To było dokładnie to, co chciałem potwierdzić ... Powinny one być równoważne w moim przypadku :) – tmarwen

0

Kiedy sprawdzili realizację Znalazłem następujące

public final boolean getAndSet(boolean newValue) { 
    for (;;) { 
     boolean current = get(); 
     if (compareAndSet(current, newValue)) 
      return current; 
    } 
} 

Również podczas sprawdzania javadoc, compareAndSet ustawia wartość tylko wtedy, gdy przejście porównania podczas getAndSet po prostu ustaw wartość i zwróć poprzednią wartość.

6

Można spojrzeć na kod dla lepszego zrozumienia:

public final boolean getAndSet(boolean newValue) { 
    for (;;) { 
     boolean current = get(); 
     if (compareAndSet(current, newValue)) 
      return current; 
    } 
} 

W getAndSet, jeśli wartość logiczną zmieniła między czasie get() stara wartość i czas próby zmiany jego wartości, compareAndSet nie zmieni jej wartości. Dlatego getAndSet wywołuje compareAndSet w pętli, dopóki wartość boolowska nie zostanie ustawiona na nową wartość.

Jak na swoim przykładzie kodu:

flag.getAndSet(false) zwraca starą wartość AtomicBoolean.Z drugiej strony, flag.compareAndSet(x,false) (zauważ, że są dwa argumenty) zwraca, czy AtomicBoolean został zmodyfikowany, lub innymi słowy, zwraca, czy stara wartość AtomicBoolean była x.

Powiązane problemy