11

Clojure STM(dosync)アプローチとJava同期ブロックの違いは何ですか?

「居眠り床屋」の問題から以下のコードを読んでいます。(http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-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))))

競合状態を回避するためにdosyncが使用されているので、「Java同期ブロックとの違い(STM)は何ですか?」と自問します。この重要なコードをブロックしますか?

前もって感謝します !ダンタス

4

4 に答える 4

21

dosyncsynchronized完全に異なる並行性の抽象化へのアクセスを提供します。

synchronizedロックを取得および解放する方法です。スレッドがsynchronizedブロックに入ると、適切なロックを取得しようとします。ロックが現在別のスレッドによって保持されている場合、現在のスレッドはブロックされ、ロックが解放されるのを待ちます。これにより、デッドロックのリスクなどの特定の問題が発生します。スレッドがsynchronizedブロックを離れると、ロックが解除されます。

dosyncトランザクションで実行されるコードのブロックをマークします。Clojureのトランザクションは、Refs(ref関数で作成されたオブジェクト)への変更を調整する方法です。Clojureの可変状態の一部を一貫して表示するためのコードが必要な場合(場合によってはそれらを変更する場合)、それらをRefsに配置し、トランザクションでコードを実行します。

トランザクションには、特定の最大再試行回数(現在は10000にハードコードされている)まで、何らかの理由でコミットできない場合に再起動するという興味深い特性があります。トランザクションがコミットできない理由として考えられるのは、世界の一貫したビューを取得できないことです(実際には、関連する参照-「適応型の履歴」機能があり、これにより、見た目よりも問題が少なくなります。一目); 他のトランザクションによって行われた同時変更。等

トランザクションはデッドロックのリスクを負いません(プログラマーがJava相互運用機能を介してSTMシステムに関係のないデッドロックを導入するために邪魔にならない限り)。一方、livelockは、可能性は低いですが、特定の可能性があります。一般的に、すべてではありませんが、多くの人がいます。--プログラマーがデータベーストランザクションに関連付ける直感のうち、Clojureを含むSTMシステムのコンテキストで有効です。

STMは大きなトピックです。ClojureのSTMについて学ぶための優れたリソースの1つは、MarkVolkmannのSoftwareTransactionalMemoryの記事です。最後のセクションでClojureのSTMについて詳しく説明しますが、最初の部分は入門書として役立ちます。

dosync引用したスニペットに関しては、ブロックはほとんどの場合副作用がないはずなので、実際には本番コードで通常エミュレートしたいものではありません。ここはprintSTMの内部動作を示すのに役立ちますが、トランザクションで実際のコードに副作用を引き起こす場合は、その目的のためにClojureエージェントを生成する必要があります(トランザクションの場合にのみタスクを実行します)正常にコミットします)。

于 2010-08-27T11:47:44.313 に答える
3

また、STMトランザクションを使用したMichałの優れた回答に加えて、読み取りは常にトランザクションの開始時に凍結された値を取得し、進行中のトランザクションが完了するのを待つ必要はありません。

于 2010-08-27T13:39:14.767 に答える
3

探している人に全体像を示すために、Clojureにはsynchronizedアナログがあります。相互運用のためにJavaの非スレッドセーフタイプを使用する必要がある場合に役立ちます。

(locking x & body)
于 2010-11-03T00:29:05.227 に答える
0

基本的な違いは次のとおりです

Clojure STMは楽観的同時実行性をサポートしますが、JAVA同期は悲観的です

Clojure STMは、複数のスレッドが存在するまでロックを取得しません。可変状態が別のスレッドによって更新された場合、dosync内の操作が繰り返されます。また、可変状態にはdosyncが必須です。JAVAとは異なり、dosyncが欠落している場合、ClojureはillegalState例外をスローします。

于 2016-04-10T16:21:11.227 に答える