Wie wird der gleichzeitige Zugriff auf eine Scala-Sammlung gehandhabt?

8

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.

    
fwielstra 24.11.2011, 11:02
quelle

4 Antworten

10

Sehen Sie sich die scala.collection.mutable.Synchronized * Merkmale / Klassen an.

Die Idee ist, dass Sie die synchronisierten Merkmale in reguläre veränderbare Sammlungen mischen, um synchronisierte Versionen von ihnen zu erhalten.

Zum Beispiel:

%Vor%     
hbatista 24.11.2011 12:24
quelle
4

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.

    
David 24.11.2011 12:32
quelle
3

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.

  • die Regel zum Senden des Actors: wo das Senden der Nachricht an einen Akteur vor dem Empfang desselben Akteurs erfolgt.
  • die nachfolgende Verarbeitungsregel des Aktors: wo die Verarbeitung einer Nachricht vor der Verarbeitung der nächsten Nachricht durch denselben Akteur erfolgt.

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."

    
Connor Doyle 24.11.2011 15:59
quelle
0
  

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.

    
Alexey Romanov 24.11.2011 12:31
quelle

Tags und Links