2010-11-18 14 views
3

Supposons que j'ai une classe Singleton (une classe peut obtenir l'instance):Java Concurrency: Mémoire partagée entre les threads

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

Supposons que j'ai plusieurs fils qui obtiennent une référence à l'instance Singleton de cette classe. J'essaie de trouver un moyen de synchroniser les get/sets sur une base PER CHAMP.

Si j'ai une méthode getter/setter synchronisé pour chaque variable, alors ce sera « verrouiller » essentiellement toute la classe (au lieu du champ individuel) jusqu'à cette méthode est définie.

est-il un moyen pour que ces fils se bloquent uniquement les valeurs d'instance au lieu de bloquer toute la classe?

- EDIT: Je présente mes excuses pour les énormes données d'un objet. données

est stocké dans plusieurs classes. Au plus, chaque objet n'a que 20-25 membres.

+3

Je pense que ma tête va exploser. Ne pouvez-vous pas simplement réduire la mutabilité? Par exemple. * enlever * le besoin de verrouiller-énorme-monolithique-icky-objet. –

+4

Mon visage a fondu en pensant à cela. – MattC

+1

Avez-vous déterminé qu'il y a un goulot de bouteille performant si vous partagez un verrou? Notez que vous pouvez verrouiller un objet 1000 fois sur plusieurs threads en environ 2 ms. Essentiellement, avant de rendre votre application encore plus compilée, avez-vous mesuré ce goulot d'étranglement ou devinez-vous? –

Répondre

5

Si j'ai une méthode getter/setter synchronisé pour chaque variable, alors ce sera « verrouiller » essentiellement toute la classe (au lieu du champ individuel) jusqu'à cette méthode est définie.

Bien, non. Il se verrouille tout l'objet, mais c'est probablement ce que vous vouliez dire quand même ...

données a des variables ... 1000

Option 1

Si vous avez assez de mémoire, vous pouvez simplement avoir un Object[] locks = new Object[1000]; pour lequel vous acquérez les verrous.

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

Option 2

Une autre option peut être de marquer tous les champs volatile. Cela permettra au moins de s'assurer que les lectures et les écritures sont effectuées de manière atomique.

Option 3

Jetez un oeil à AtomicLong, AtomicReference, AtomicBoolean, ... et ainsi de suite dans le java.util.concurrent.atomic package.

+0

Volatile était ce que je cherchais. Merci! –