J'ai une classe Singleton qui est partagée dans plusieurs threads. Pour éviter de multiples problèmes d'accès, j'utilise la méthode de verrouillage lors de l'accès à une ou à une autre propriété de la classe. La question serait possible d'améliorer le code et de mettre la méthode de verrouillage à l'intérieur de la classe Singleton plutôt que de la mettre à chaque fois lorsque la propriété de classe est accessible en code?
4 Réponses :
Ceci est le modèle de thread-sécurisé Singleton que j'utilise au cas où vous seriez intéressé:
public class DataAccess { #region Singleton private static readonly object m_SyncRoot = new Object(); private static volatile DataAccess m_SingleInstance; public static DataAccess Instance { get { if (m_SingleInstance == null) { lock (m_SyncRoot) { if (m_SingleInstance == null) m_SingleInstance = new DataAccess(); } } return m_SingleInstance; } } private DataAccess() { } #endregion }
Si cela est activement utilisé, la première chose est de supprimer les préfixes horribles m _ code>.
Votre réponse ne répond pas à ma question. Je demande comment réduire les méthodes de verrouillage dans le code et mettre en place la classe à l'intérieur de la classe pour verrouiller les propriétés.
@ Mr.Disappointment Note très importante que vous avez fait là-bas! Toutes nos félicitations! Retour à la question et à ses réponses, avez-vous quelque chose d'utile pour suggérer à la personne qui posa la question?
+1 Ceci est l'initialisateur de fil de sécurité Singleton définitif, voir Cette page MSDN pour référence , vous devez utiliser volatile code> et vous devez utiliser un verrouillage
code> sur le getter, vous ne pouvez pas réduire cela plus loin.
@Tomas oui vous avez raison, j'ai mal compris la question un peu. Pour ce que vous êtes vraiment demandé, j'ai ma propre règle. Si la propriété a une partie définie ou qu'il y a une sorte de dessous d'initialisation dans la partie GET, j'utilise toujours la serrure.
J'utilise toujours la serrure, mais avez-vous une idée de la manière d'améliorer le code et de verrouiller la classe à l'intérieur de la classe sur les propriétés plutôt que d'écrire une propriété à chaque propriété est accessible?
Je pense que ce que vous avez demandé est une question de ce que votre classe fait. Si vous pouvez effectuer des méthodes qui maintiennent les propriétés de la classe tous ensemble, alors faites simplement la serrure et laissez vos propriétés d'obtenir simple. Mais si ce n'est pas ce que vous voulez, je suis désolé mais je ne peux voir aucune autre solution que de verrouiller le code des propriétés.
IMHO, c'est La solution définitive pour un verrouillage de fil-sécurité dans un singleton. De celui-ci (cinquième sur la liste):
+1 J'ai vu cette solution pendant un moment où aller, et cherchait à poster comme réponse. C'est la meilleure solution que je suppose, pas de serrures et ne crée pas d'instance jusqu'à ce que vous en ayez besoin.
Votre réponse ne répond pas à ma question. Je demande comment réduire les méthodes de verrouillage dans le code et mettre en place la classe à l'intérieur de la classe pour verrouiller les propriétés. Vous montrez comment verrouiller une nouvelle initialisation d'instance.
@Tomas: Si la propriété est configurée de cette façon, vous n'avez pas besoin de verrous explicites. C'est un peu tout le point.
HMM intéressant, je vais le tester et vous le faire savoir.
@Yuck: Vous faites mal à la question. Les serrures sont encore nécessaires lors de l'ajout à la liste ou incrémentent le compteur.
C'est aussi un très bon schéma de fil singleton. La seule raison pour laquelle je préfère celui que j'ai posté, est-ce que, en général, je n'aime pas les classes imbriquées. Mais c'est moi!
Ceci est assez commun. Verrouillage / déverrouillage dans les getters / Setters est beaucoup plus sûr (vous ne pouvez pas oublier de le faire), et plus pratique, (la verrouillage ne doit pas nécessairement être directement accessible partout que vous utilisez la propriété), qu'un verrou extérieur sur chaque accès de propriété . P>
rgds, Martin P>
True, cependant, du lien que j'ai affiché: "Malheureusement, la performance souffre de verrouillage à chaque fois que l'instance est demandée."
... et par la façon dont je ne t'ai pas révélé. En fait, je ne pense pas ce que vous avez écrit mérite un bowvote.
De plus, je ne dirais pas que cela est la meilleure pratique - les verrous devraient être acquis avec une minimalité, à la fois en termes d'exécution et celui de la portée - avoir à acquérir et à libérer une serrure dans toutes les propriétés d'une classe que vous souhaitez faire du thread-Safe est inefficace. et i> plus difficile à maintenir.
Eh bien, peut-être que je aurais peut-être qualifié ma réponse avec "dépend de ce que les Setters / getters font". S'ils ne sont que définir / obtenir des données membres, le temps passé à l'intérieur de la serrure serait très petit et la possibilité de contention de même. Le problème avec une stratégie de verrouillage étendue sur la propriété individuelle Lecture / écriture est que cela se transforme souvent sur une stratégie de manœuvre étendue. Plus les serrures, et plus la stratégie de verrouillage est complexe, plus il est difficile d'empêcher les problèmes, en particulier avec le développement continu: chaque fois que vous ajoutez / modifier la fonctionnalité interne, vous devez revisiter le verrouillage :(
Supprimer ces propriétés: ... et remplacer par des méthodes telles que (désolé pseudo-code, je ne peux pas être dérangé pour penser aujourd'hui): p> ServerStatus code> doit conserver sa propre synchronisation, pas les clients externes de cette classe. Cela étant dit, vous devrez refacteur
ServerStatus CORE> et créer quelques méthodes de thread-coffre (avec verrouillage):
Liste publique
pistonqueue réelle code>. p>
+1 C'est ce que je lui ai également suggéré, mais vous l'avez décrit mieux!