2012-03-12 15 views
7

Hi guys: Dokumentacja dla Clojure „atom” stwierdza, że ​​-warunki wyścigu i Atomy Clojure

"Changes to atoms are always free of race conditions." 

However- warunkiem rasa nie jest zdefiniowana tylko w kategoriach zmiany, ale raczej w kontekście równoległe operacje logiczne w różnych wątkach.

Zastanawiam się - jakie jest znaczenie gwarancji, że "Zmiany w atomach są zawsze wolne od warunków wyścigu"? W języku java mamy prymitywy atomowe, które obsługują określone wątkowe operacje, które są specyficzne (na przykład AtomicInteger obsługuje operację "getAndIncrement"). A atomy clojure są typu niezależnej od, na przykład, może to wywołać:

(atom "Hi im a string") Or 
    (atom (.getClass Object)) 

elastyczność sposobu atom oznacza Clojure pod maską nie jest „elegancko” dostarczanie typ specyficznych atomowy/wątku bezpieczny operacje dla atomów.

Zatem chciałbym zapytać - co dokładnie jest metoda atom „robi” do naszych obiektów

Odpowiedz

11

atom jest skutecznie atomowej miejsce przechowywania, które jest gwarantowane (czyli jest to po prostu synchronizacji całego obiektu?) być bezpieczny dla wątków.

Atomy są podobne do atomowych typów danych Javy (takich jak AtomicReference), ale w rzeczywistości są nieco bardziej wydajne, ponieważ atom pozwala na użycie dowolnej funkcji do aktualizacji atomu. Przykład:

(def a (atom "foo")) 

(defn appender [x] 
    "Higher order function that returns a function which appends a specific string" 
    (fn [s] 
    (str s x))) 

(swap! a (appender "bar")) 
=> "foobar" 

W powyższym przykładzie, operacja swap! zachowuje atomowo, mimo że działanie appender my przejściu z nim może być potencjalnie bardzo złożone funkcje. W efekcie atomy pozwalają na użycie arbitralnej operacji aktualizacji w sposób atomowy (powinieneś normalnie trzymać się czystych funkcji, ponieważ funkcja może być wywołana wiele razy w przypadku rywalizacji).

Atomy oczywiście nie gwarantują bezpieczeństwa nici umieszczanych w nich obiektów (np. W przypadku umieszczenia niezsynchronizowanej tablicy Java ArrayList w środku, to nadal nie jest bezpieczne w przypadku równoczesnego użytkowania). Jeśli jednak pozostaniesz niezmiennymi typami danych Clojure, które są całkowicie bezpieczne dla wątków, będziesz dobry.

+5

* "Gwarantujemy, że funkcje te będą wykonywane sekwencyjnie" * - nie jest to dokładnie to, co gwarantuje "atom". Rzeczywistą gwarancją jest, że 'swap af' zapamiętuje wartość' a', przekazuje ją do 'f' i jeśli wartość' a' po zakończeniu 'f' jest nadal równa starej wartości, to jest ona zastępowana przez wynik 'f'. W międzyczasie wiele innych funkcji można było zastosować do 'a', o ile ich efekty znoszą się nawzajem. –

+1

@Rafal - dziękuję, poprawiłem odpowiedź, aby była nieco bardziej precyzyjna. – mikera

+0

@myself: Podstawowym porównaniem jest w rzeczywistości Java == (tożsamość obiektu), więc zamiast "równy" powinienem napisać "identyczny" i zamiast "anulować się nawzajem" -> "zostaw atom odwołujący się do tego samego obiektu" . –