Ich habe einen Akteur, der - in seiner Essenz - eine Liste von Objekten unterhält. Es hat drei grundlegende Operationen, ein Add, ein Update und ein Remove (wobei manchmal das Entfernen von der Add-Methode aufgerufen wird, aber das abgesehen), und arbeitet mit einer einzelnen Sammlung. Offensichtlich wird auf diese Backing-Liste gleichzeitig zugegriffen, wobei Add- und Remove-Aufrufe sich gegenseitig verschachteln.
Meine erste Version verwendet einen ListBuffer, aber ich habe irgendwo gelesen, dass es nicht für den gleichzeitigen Zugriff gedacht ist. Ich habe keine Ausnahmen für den gleichzeitigen Zugriff erhalten, aber ich habe festgestellt, dass das Finden von & amp; das Entfernen von Objekten funktioniert nicht immer, möglicherweise aufgrund von Nebenläufigkeit.
Ich habe es halb neu geschrieben, um eine var-Liste zu verwenden, aber das Entfernen von Elementen aus der unveränderlichen Liste von Scala ist ein bisschen mühsam - und ich bezweifle, dass es für den gleichzeitigen Zugriff geeignet ist.
Grundlegende Frage: Welcher Sammlertyp sollte ich in einer Situation mit gleichzeitigem Zugriff verwenden und wie wird er verwendet?
(Vielleicht sekundär: Ist ein Actor tatsächlich eine Multithread-Entity, oder ist das nur meine falsche Vorstellung und verarbeitet er Nachrichten einzeln in einem einzigen Thread?)
(Tertiär: In Scala, welcher Sammlertyp ist am besten für Einsätze und wahlfreien Zugriff (Löschen / Aktualisieren)?)
Edit: An die freundlichen Responder: Entschuldigen Sie meine späte Antwort, ich mache mir eine üble Angewohnheit daraus, eine Frage auf SO oder Mailinglisten abzuladen, dann gehe ich zum nächsten Problem über und vergesse das Original für den Moment.
Sie müssen den Status der Akteure nicht synchronisieren. Das Ziel der Akteure ist es, knifflige, fehleranfällige und schwer zu debuggende konkurrierende Programmierung zu vermeiden.
Das Actor-Modell stellt sicher, dass der Akteur Nachrichten nacheinander aufnimmt und dass Sie nie zwei thread-konsumierende Nachrichten für den gleichen Actor haben werden.
Die unveränderlichen Sammlungen von Scala eignen sich für die gleichzeitige Verwendung.
Was die Schauspieler betrifft, so sind einige Dinge garantiert, wie hier erklärt Akka Dokumentation.
Sie können nicht garantieren, dass derselbe Thread die nächste Nachricht verarbeitet, aber Sie sind garantiert, dass die aktuelle Nachricht die Verarbeitung abschließt, bevor die nächste gestartet wird, und auch zu einem bestimmten Zeitpunkt nur eine Thread führt die Empfangs-Methode aus.
Damit wird auf den persistenten Zustand eines bestimmten Actors geachtet. Im Hinblick auf geteilte Daten ist der beste Ansatz, so wie ich es verstehe, die Verwendung unveränderlicher Datenstrukturen und die größtmögliche Anlehnung an das Actor-Modell. Das heißt: "Kommuniziere nicht durch Teilen von Speicher; teile Speicher durch Kommunizieren."
Welcher Sammlertyp sollte ich in einer Situation mit gleichzeitigem Zugriff verwenden und wie wird er verwendet?
Siehe @ hbatistas Antwort.
Ist ein Actor tatsächlich eine Multithread-Entity, oder ist das nur meine falsche Vorstellung und verarbeitet er Nachrichten einzeln in einem einzigen Thread
?
Die zweite (obwohl der Thread, auf dem Nachrichten verarbeitet werden, sich ändern kann, also speichern Sie nichts in lokalen Thread-Daten). Auf diese Weise kann der Schauspieler Invarianten in seinem Zustand beibehalten.
Tags und Links scala concurrency collections