Frage

Was ist der Unterschied zwischen Clojure STM (DoSync) Ansatz und Java synchronisieren blockieren?

Ich lese den Code von „Der Schlaf Barbier“ -Problem. ( http: // www .bestinclass.dk / index.clj / 2009/09 / scala-vs-clojure-rund-2-concurrency.html )

(defn the-shop [a]  
  (print "[k] entering shop" a)  
  (dosync     
    (if (< (count @queue) seats)  
      (alter queue conj a)  
      (print "[s] turning away customer" a))))

Um zu vermeiden, Rennbedingungen wird dosync verwendet, so frage ich mich: „Was ist der Unterschied (STM) von Java synchronisieren Block“? Wird es diesen kritischen Code blockieren?

Vielen Dank im Voraus! Dantas

War es hilfreich?

Lösung

dosync und synchronized den Zugang zu völlig anderen Gleichzeitigkeit Abstraktionen.

synchronized ist eine Möglichkeit für den Erwerb und Freigeben von Sperren. Wenn ein Thread einen synchronized Block eintritt, versucht es, die entsprechende Sperre zu erwerben; Wenn die Sperre gegenwärtig von einem anderen Thread, den aktuellen Thread Blöcke und wartet auf sie freigegeben werden gehalten wird. Dies führt zu bestimmten Problemen, wie zum Beispiel das Risiko einer Sackgasse. Die Sperre wird freigegeben, wenn die Fäden Blätter des synchronized Block.

dosync markiert einen Block von Code, der in einer Transaktion ausgeführt werden soll. Transaktionen in Clojure sind eine Möglichkeit von Änderungen an Refs Koordinieren (Objekte mit der ref Funktion erstellt); wenn Sie einen Code benötigen eine konsistente Sicht auf einige Stücke von wandelbarem Zustand in Clojure haben - und sich möglicherweise ändern -. Sie diejenigen in Refs setzen und Ihren Code in einer Transaktion ausgeführt

Eine Transaktion die interessante Eigenschaft hat, dass es neu gestartet wird, wenn aus irgendeinem Grunde kann es nicht verpflichten, bis zu einer bestimmten maximalen Anzahl von Wiederholungen (derzeit hartcodiert 10000 zu sein). Zu den möglichen Gründen für eine Transaktion zu begehen nicht in der Lage ist eine Unfähigkeit, eine konsistente Sicht der Welt zu erhalten (tatsächlich die relevante Refs - gibt es eine „adaptive Geschichte“ Einrichtung, die dies weniger ein Problem macht, als es scheinen mag an erster Blick); gleichzeitige Änderungen durch andere Transaktionen vorgenommen; etc.

Eine Transaktion läuft keine Gefahr von Deadlocks (es sei denn der Programmierer aus dem Weg geht ein Deadlock in keinem Zusammenhang mit dem STM-System durch Java-Interop einzuführen); Livelock, auf der anderen Seite, ist eine gewisse Möglichkeit, obwohl es nicht sehr wahrscheinlich ist. In der Regel viele - wenn auch nicht alle! - die Intuitionen Programmierer mit Datenbank-Transaktionen zuzuordnen sind im Rahmen von STM-Systemen gültig, einschließlich der von Clojure

.

STM ist ein großes Thema; eine hervorragende Ressource für über Clojure STM Lernen ist Mark Volkmannsche Software Transactional Memory Artikel. Es geht in große Tiefe in Clojure STM in seinen letzten Abschnitten diskutieren, aber der Anfang als große einleitende Lesung dienen.

Wie für das Snippet Sie zitiert, es ist eigentlich nicht etwas, das man normalerweise wollen würde in der Produktion Code emulieren, da dosync Blöcke sollten fast immer Nebeneffekt frei sein; der print hier kann zum Nachweis der innere Funktionsweise des STM nützlich sein, aber wenn Sie eine Transaktion zu verursachen Nebenwirkungen in echtem Code wollen, sollten Sie es zum Zweck eines Clojure-Agenten laichen (die nur ihre Aufgabe ausführen würde, wenn die Transaktion erfolgreich verpflichtet).

Andere Tipps

Auch neben Michals ausgezeichnete Antwort, mit STM-Transaktionen, liest immer erhalten Sie die gefrorenen Wert zu Beginn der Transaktion und müssen nicht für jede laufende Transaktion abzuschließen warten.

Nur ein vollständiges Bild für diejenigen, die geben, tut Clojure eine synchronized Analog haben. Es ist nützlich, wenn man mit Java nicht-Thread-Typen für Interop Arbeit hat.

(locking x & body)

grundlegender Unterschied folgt

Clojure STM unterstützt optimistisch Parallelität während JAVA synchronisiert ist Pessimist

Clojure STM erwirbt keine Sperre, bis es mehr als ein Thread ist. wenn wandelbarer Zustand von einem anderen Thread aktualisiert wird dann der Operation innerhalb von DoSync wiederholt. Auch DoSync ist obligatorisch für wandelbar Staaten. Clojure wirft illegalState Ausnahme, wenn DoSync fehlt, im Gegensatz zu JAVA.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top