単一のフィールドを持つアクターがいるとします。アクターへの100メッセージごとに99が値を読み取り、100番目が値を更新します。この場合、読み取りを並行して処理したいと思います。つまり、アクターを使用して読み取り/書き込みロックのパフォーマンスを実現するにはどうすればよいですか?これはScala標準のアクターやAkkaで実用的ですか?または私は俳優のポイントを逃していますか:)
更新:紛らわしい言葉を修正しました、申し訳ありません
あなたはおそらく俳優の要点を見逃しているでしょう。クエリを送信するアクターが必要であると想定しています。その後、アクターは応答を返します。アクターにメッセージを送信し、それを処理し、応答を送り返すには、かなりの量の機械が関係しています。応答メッセージの実際の生成はタスクとして作成され、スレッドプールに送信されます。メッセージキューとスレッドプールの間には、ロックまたはせいぜいCAS操作を必要とする場所が複数あります。通常、ポイントは、アクターがそのメッセージに基づいて別のスレッドで何らかの作業を行うことです。
データの読み取りと書き込みをほとんど行わない場合(カウンターのインクリメントやマップ内の値へのアクセスなど)は、java.util.concurrentの適切なクラスを使用することをお勧めします。
[免責事項:私はAkkaのPOです]
代わりにエージェントを使用することをお勧めします。読み取りはいつでも実行できますが、一度に1つの書き込みしか実行できません。
http://doc.akkasource.org/agents-scala
編集:http ://doc.akka.io/docs/akka/2.1.0/scala/agents.html (このリンクを試してください)
すべてのメッセージが不変であり、ほとんどすべてのメッセージがアクターの状態を変更しないことを意味していると思います。この場合、アクターはおそらくデザインの最良の選択ではありません。アクターを使用すると、シングルスレッドコードを処理しているかのように、可変状態を管理できます。
事実上、各アクターには、メッセージが送信されてから一度に1つずつ処理されるメールボックスがあります。あなたのシナリオでは、これはかなり無駄になります。提案されているように、java.util.concurrentの何かを使用するのが最も効果的です。
アクターは、メッセージを連続して処理するように設計されています。これにより、推論が容易になります。一度に1つのメッセージを受け取るため、アクター内の変数(他の誰かによって変更されていない限り)は、並行性を考慮せずに変更できます。これは最も効率的な方法ですか?絶対違う!しかし、正しく機能するやや非効率的なコードは、壊れた非常に効率的なコードよりもほとんどの場合優れています。
あなたが求めているのは正反対です。処理速度を上げるために、同時実行性(「アクセスの99%が読み取りであり、したがって並行して発生する可能性があることを知っています!」)について明確に考えたいと考えています。この場合、おそらくjava.util.concurrent.locks.ReentrantReadWriteLock
、可変変数へのアクセスを直接制御するために使用する必要があります(で見つかったアクセスのタイプが機能java.util.concurrent.atomic._
しない場合)。ロックを正しく行うという負担を負ったことを忘れないでください。適切に注意してください。