0
votes

Ce code n'est pas threadsafe - a-t-il besoin d'être?

J'ai une classe, qui, fortement simplifiée par les pièces pertinentes, ressemble à ceci (noms factices): xxx

un coéquipier a commenté que le chèque de Store == null n'est pas threadsafe, car la valeur de Store pourrait changer entre les threads. Cependant, nous ne sommes pas sûrs que cela importera car rien ne règle jamais le magasin sur NULL, et je ne vois pas de problème avec plusieurs threads essayant de définir le même Store à New SomedatASTore (...) car le magasin de données est en lecture seule à partir du code.

Y a-t-il des problèmes avec la sécurité de thread de cette sécurité?

Merci!


3 commentaires

Oui. Vous oubliez que pendant que les ordinateurs simulent de faire des choses dans l'ordre que vous leur dites, en réalité, ils réorientent tout, gardant à l'esprit produire le même effet comme si elles n'étaient pas réorganisées. Produire le même effet, jusqu'à ce que le fil actuel est concerné . D'autres threads pourraient voir votre objet somédatastore partiellement créé lorsqu'ils ont sauté le si. Et tout état incompatible. Vous pouvez atténuer cela en faisant du magasin volatil, ses accès ne seront pas réorganisés alors.


Bien qu'il soit préférable d'initialiser vos objets à l'exécution, puis de commencer les threads qui les utilisent.


Les réponses jusqu'à présent n'ont pas mentionné le modèle de mémoire Java. Les fils doivent non seulement coordonner les sections critiques (zones où les threads pourraient en conflit), mais peuvent avoir à partager des données entre elles. Le partage des données entre les threads nécessite une coordination (en utilisant synchronisé et d'autres idiomes) non seulement pour le séquencement, mais également pour rendre les modifications visibles les unes aux autres. Réglage Store = null est redondant dans une variable de membre. Pourquoi ne pas simplement la définir directement à la valeur nécessaire au lieu d'instantiquer la paressologie?


3 Réponses :


0
votes

La réponse courte est que vous devriez vous efforcer d'écrire votre code d'une manière qui le fera de la sécurité. Maintenant, pour la longue réponse: aussi loin que vous pouvez dire que votre code n'a pas de problèmes dès maintenant en raison de cette opération dangereuse. En supposant que vous êtes un prodige et que vous avez réalisé la bonne évaluation concernant la situation actuelle, en permettant à votre base de code, vous avez ajouté une forme de dette, une partie de code qui pourrait facilement s'avérer problématique à l'avenir et peut créer difficile à trouver Bugs. Il est difficile de dire que vous essayez d'essayer de créer un champ mis en cache, il existe des moyens de faire en sécurité ce fil.


0 commentaires

1
votes

Dans l'exemple donné, s'il existe plusieurs threads appelant la méthode - "gettoreattributes ()", la variable d'instance "Store" pourrait être initialisée deux fois. Si, dans votre cas, c'est bien d'initialiser la variable de magasin plusieurs fois, c'est bien, il n'est pas nécessaire d'ajouter une sécurité de thread. Si vous ne souhaitez pas ajouter de fonctionnalités de sécurité de thread, telles que le bloc synchronisé, faites au moins une variable de "Store" volatiles de la variable qui garantira que les threads liront la dernière état de la mémoire.

mais à partir du nom "Store" ressemble à une ressource et l'initialisation de plusieurs fois sans raison ne semble pas correcte. Et vous pouvez économiser cela en ajoutant la sécurité du fil. Si un thread d'initialisation de la ressource, d'autres attendent et utilisent la ressource initialisée. Vous pouvez implémenter un double verrouillage pour assurer la même chose.


0 commentaires

2
votes

Y a-t-il des problèmes avec la sécurité du fil de ceci?

Oui. Au moins ces:

  • Si vous avez une instance de Someclass qui est partagée entre deux fils ou plus, au moins une de ces threads définit jamais le membre Store Membre sur un autre - NULL valeur et tout autre thread invoque getStoreAttributes () sur cette instance, vous avez une course Data . Dans ce cas, le comportement de votre programme est indéfini.

  • parmi les comportements qui peuvent être observés dans la pratique avec une course de données telle que celle-ci sont

    • Un ou plusieurs threads jamais observe la mise à jour de Store
    • Différents threads observe la mise à jour de Store dans les commandes qui semblent mutuellement incohérentes
    • même si vous pouviez supposer que cela se lit et écrit à Store était atomique, de sorte qu'il n'y avait pas de race de données, vous toujours aurait le problème que deux Différents threads pourraient tous les deux observer Store pour être null et entrez le bloc si bloc en même temps. En conséquence, ils instancieraient chacun un nouveau SomedATASTore , que la méthode reviendrait, vaincre l'objet apparent.


0 commentaires