2010-11-18 13 views
3

Angenommen, ich habe eine Singleton-Klasse (jede Klasse kann die Instanz erhalten):Java Concurrency: Shared Memory zwischen Threads

class data 
{ 
     Color sun = "WHITE"; 
     String luminance = "HIGH"; 
     int age = 25; 
     double speed = 52.5 
     ... 
} 

nehme ich mehrere Threads haben, die einen Verweis auf die Singleton Instanz dieser Klasse zu bekommen. Ich versuche, einen Weg zu finden, gets/sets auf einer PER FIELD Basis zu synchronisieren.

Wenn ich eine synchronisierte Getter/Setter-Methode für jede Variable habe, dann "sperrt" dies die ganze Klasse (anstelle des einzelnen Feldes), bis diese Methode gesetzt ist.

Gibt es eine Möglichkeit, dass diese Threads nur Instanzwerte sperren, anstatt die gesamte Klasse zu sperren?

- BEARBEITEN: Ich entschuldige mich für die riesigen Daten eines Objekts.

Daten werden tatsächlich in mehreren Klassen gespeichert. Höchstens jedes Objekt hat nur 20-25 Mitglieder.

+3

Ich denke, mein Kopf wird explodieren. Können Sie nicht einfach die Wandlungsfähigkeit reduzieren? Z.B. * entfernen * die Notwendigkeit zu sperren-riesig-monolithisch-icky-Objekt. –

+4

Mein Gesicht hat abgeschwächt darüber nachzudenken. – MattC

+1

Haben Sie festgestellt, dass es einen Flaschenhals gibt, wenn Sie ein Schloss teilen? Beachten Sie, dass Sie ein Objekt in etwa 2 ms 1000 Mal über mehrere Threads hinweg sperren können. Bevor Sie Ihre Bewerbung noch kompilierter machen, haben Sie diesen Engpass gemessen oder schätzen Sie? –

Antwort

5

Wenn I ein synchronisiertes Get-/Set-Verfahren für jede Variable hat, dann wird diese im Allgemeinen „sperren“, die ganze Klasse (anstelle der einzelnen Feld), bis das Verfahren eingestellt wird.

Nun, nein. Es wird das gesamte Objekt sperren, aber das ist wahrscheinlich das, was Sie sowieso ... 1000+ Variablen

Daten hat

gemeint ...

Option 1

Wenn Sie Genug Speicher, Sie könnten einfach eine Object[] locks = new Object[1000]; haben, für die Sie die Sperren erhalten.

public void setColor(Color newCol) { 
    synchronized (locks[17]) { 
     sun = newCol; 
    } 
} 

Option 2

Eine weitere Option, um alle Felder als volatile angreifen könnten. Dies stellt zumindest sicher, dass die Lese- und Schreibvorgänge automatisch ausgeführt werden.

Option 3

Werfen Sie einen Blick auf AtomicLong, AtomicReference, AtomicBoolean, ... und so weiter in der java.util.concurrent.atomic package.

+0

Volatile war was ich suchte. Vielen Dank! –