8
votes

Si plus d'un thread peut accéder à un champ, il doit être marqué comme volatilité?

lire quelques threads ( Problèmes communs de simultanéie , Mot-clé volatile , Modèle de mémoire ) Je suis confus sur les problèmes de concurrence dans Java.

J'ai beaucoup de champs accessibles par plus d'un fil. Dois-je les passer à travers et les marquer tous comme volatiles?

Lors de la construction d'une classe, je ne suis pas au courant de savoir si plusieurs threads y accéderont, il est donc dangereux de laisser n'importe quel champ pas être volatil, donc par ma compréhension, il y a très peu de cas que vous voulez 't l'utiliser. Est-ce correct?

Pour moi, cela est spécifique à la version 1.5 JVMS et plus loin, mais ne vous sentez pas limité à répondre à ma configuration spécifique.


0 commentaires

4 Réponses :


4
votes

Eh bien, vous avez lu ces autres questions et je présume que vous avez déjà lu les réponses déjà, donc je vais simplement mettre en évidence des points clés:

  1. vont-ils changer? Sinon, vous n'avez pas besoin de volatile
  2. Si oui, la valeur d'un champ est-elle liée à une autre? Si oui, allez au point 4
  3. Combien de fils vont le changer? Si seulement 1, alors volatile est tout ce dont vous avez besoin
  4. Si la réponse au numéro 2 est "non" ou plus d'un threads va y écrire, alors volatile seul est pas assez , vous aurez probablement besoin de synchroniser l'accès

    Ajouté:
    Si le champ fait référence à un objet, il aura des champs de son propre et toutes ces mesures s'appliquent également à ces champs.


0 commentaires

1
votes

La réponse courte est non. Les problèmes de filetage nécessitent plus de pensée et de planification que cela. Voir Ceci pour certaines limitations lorsqu'une volatilité aide à enfiler et quand il ne le fait pas. La modification des valeurs doit être correctement synchronisée, mais la modification de manière très typique nécessite l'état de plus d'une variable à la fois. Dites par exemple, vous avez une variable et vous souhaitez le modifier s'il rencontre un critère. La lecture de la matrice et l'écriture sur la matrice sont des instructions différentes et doivent être synchronisées ensemble. Volatile n'est pas suffisant.

Considérez également le cas où la variable références d'un objet mutable (disent un tableau ou une collection), puis interagissant avec cet objet ne sera pas en sécurité simplement parce que la référence est volatile.


0 commentaires

3
votes

Si un champ est accessible par plusieurs threads, il devrait être volatile ou final ou accessible uniquement avec des blocs synchronisés. Sinon, les valeurs attribuées peuvent ne pas être visibles pour d'autres threads.

Une classe doit être spécialement conçue pour un accès simultané par plusieurs threads. Il suffit de marquer des champs volatils ou finaux non suffisants pour la sécurité du fil. Il existe des problèmes de cohérence (atomicité des modifications apportées à plusieurs champs), préoccupations concernant la signalisation inter-thread (par exemple en utilisant attendre et notify ), etc.

Donc, il est le plus sûr de supposer qu'un objet doit être visible pour seulement un seul thread à moins qu'il ne soit documenté autrement. La fabrication de tous vos objets est un thread-coffre-fort n'est pas nécessaire et est coûteux en termes de vitesse logicielle, mais plus important encore, en termes de dépenses de développement.

Au lieu de cela, le logiciel doit être conçu de manière à ce que les threads simultanés interagissent le moins possible les uns avec les autres, de préférence pas du tout. Les points où ils interagissent doivent être clairement identifiés de manière à ce que les contrôles de concurrence appropriés puissent être conçus.


0 commentaires

2
votes

Si vous devez demander, utilisez des serrures. volatile peut être utile dans certains cas, mais c'est très difficile à obtenir. Par exemple: xxx

si deux threads exécutent incrément () en même temps, il est possible que le résultat soit compteur = 1 . En effet, l'ordinateur va d'abord récupérer compteur , ajoutez-en un, puis sauvegardez-le. Volatile force juste la sauvegarde et la charge pour se produire dans un ordre spécifique par rapport à d'autres déclarations.

Notez que synchronisé évite généralement le besoin de volatile - si Tous les accès à un champ donné sont protégés par le même moniteur, volatile ne seront jamais nécessaires.

à l'aide de volatile pour faire des algorithmes sans verrouillage est très, très difficile; Stick to synchronisé sauf si vous avez déjà une preuve difficile, et a déjà effectué une analyse détaillée sur l'algorithme que vous envisagez de mettre en œuvre.


2 commentaires

Pour ce cas d'utilisation particulière, voir AtomicInteger, plutôt que d'utiliser synchronisé vous-même.


En effet. Je voulais juste démontrer les pièges d'utiliser aveuglément en utilisant synchronisé sans comprendre exactement ce qu'il fait et ne fournit pas