Sécurité de thread pour les variables statiques
class ABC implements Runnable {
private static int a;
private static int b;
public void run() {
}
}
J'ai une classe Java comme ci-dessus. J'ai plusieurs threads de cette classe. Dans le run()
méthode, les variables a
& b
sont incrémentés à chaque à plusieurs reprises. Sur chaque incrément, je suis en train de monter ces variables dans une table de hachage.
Ainsi, chaque thread va incrémenter la fois des variables et de les mettre dans la table de hachage. Comment puis-je faire ces opérations thread-safe?
source d'informationauteur hoshang.varshney
Vous devez vous connecter pour publier un commentaire.
Je voudrais utiliser AtomicIntegerqui est conçu pour être thread-safe et est facile à utiliser morts et donne le minimum de la surcharge de la synchronisation de l'application:
Dépend de ce qui doit être thread-safe. Pour ces
int
primitives, vous aurez besoin de les remplacer avec desAtomicInteger
's ou ne fonctionnent avec eux danssynchronized
méthode ou un bloc. Si vous avez besoin pour faire de votre cross-thread Hashtable thread-safe, vous n'avez pas besoin de faire quoi que ce soit, comme c'est déjà synchronisé.Utiliser un
synchronized
méthode, par exempleCi-dessus est bon si vous êtes accédant à la statique par une instance unique, cependant si vous avez plusieurs instances, alors vous avez besoin pour synchroniser sur certains objets statiques - quelque chose comme (non testé)..
dans la méthode
REMARQUE: Ces approches supposent que vous voulez incrémenter
a
etb
dans un atomique action, les autres réponses en évidence la façon dont ils peuvent être individuellement incrémenté à l'aide de atomics.Je tiens à ajouter quelques détails au sujet de la réponse à cette question.
Tout d'abord, l'OP se pose au sujet de :
Avant de répondre à cette question, nous avons besoin pour atteindre la cohérence sur ce qui est thread-safe. La définition que j'aime surtout, c'est que de "la Java de la Simultanéité Dans la Pratique", et c'est
Si vous êtes d'accord avec la définition, cela signifie que nous devons atteindre la consistance avant de poursuivre la discussion. Revenons aux opérations que vous voulez dire, c'est
a++
etb++
après l'incrémentation, vous les mettez dans unHashTable
.Pour la
a++
opération, il n'est pas vraiment une seule opération. Il obéit au modèle de lire modifier écrire. Comme vous pouvez le voir, il contient en fait trois étapes. La lecture de la valeur, ajoutez-en une et les enregistrer en arrière. Si vous avez deux threads de lire la variablea
avec la valeur1
dans le même temps, après les modifications et enregistrer les opérations de retour. La valeur sera2
mais en fait elle devrait être3
. Pour éviter ce genre de situation, à l'instar de ce que les autres ont suggéré, vous pouvez utiliserAtomicInteger
au lieu deint
taper directement. LeAtomicInteger
sera une garantie de certaines opérations comme l'incrément à exécuter de manière atomique. Cela signifie que le lire modifier écrire opérations ne peut pas être divisé et sera exécutée comme une étape individuelle.Après cela, l'OP veut enregistrer la valeur dans une table de hachage. La table de hachage est un fil contenant sécuritaire, aucun autre synchronisation nécessaire.
Espérons que cette clarification peut aider quelqu'un d'une autre manière. Merci.