Je ne pense pas que quelqu'un a réellement répondu à la question, donc je vais lui donner un essai.
De la volatilité et de la première if (instance == null)
ne sont pas "nécessaires". La serrure se rendre ce code thread-safe.
La question est donc: pourquoi voudriez-vous ajouter le premier if (instance == null)
?
La raison en est sans doute pour éviter l'exécution de l'verrouillé section de code inutilement. Pendant que vous exécutez le code à l'intérieur de la serrure, aucun autre thread qui tente également d'exécuter ce code est bloqué, ce qui va ralentir votre programme vers le bas si vous essayez d'accéder à l'singleton fréquemment à partir de plusieurs threads. En fonction de la langue/plate-forme, il pourrait également y avoir des frais généraux de la serrure en elle-même que vous voulez éviter.
Donc, la première null check est ajouté comme un moyen rapide de voir si vous avez besoin de la serrure. Si vous n'avez pas besoin de créer le singleton, vous pouvez éviter le verrouillage entièrement.
Mais vous ne pouvez pas vérifier si la référence est nulle sans verrouillage d'une certaine façon, parce qu'en raison de la mise en cache du processeur, un autre thread pourrait changer et que vous lisez un "vicié" valeur qui pourraient vous amener à rentrer dans la serrure inutilement. Mais vous êtes en essayant d'éviter un lock!
Donc, vous faites le singleton volatile pour s'assurer que vous avez lu la dernière valeur, sans avoir à utiliser un verrou.
Vous devez toujours l'intérieure de verrouillage car volatils seulement vous protège lors d'un accès unique à la variable, vous pouvez pas test-and-set en toute sécurité sans l'aide d'un verrou.
Maintenant, est-ce vraiment utile?
Eh bien je dirais que "dans la plupart des cas, aucune".
Si Singleton.Exemple, pourraient entraîner l'inefficacité due à l'serrures, alors pourquoi êtes-vous de l'appeler si souvent que cela serait un problème important? Le point de l'ensemble d'un singleton est qu'il y est un seul, de sorte que votre code peut lire et cache le singleton de référence une fois.
Le seul cas que je peux penser d'où cette mise en cache ne serait pas possible lorsque vous avez un grand nombre de threads (par exemple, un serveur à l'aide d'un nouveau thread pour traiter chaque demande pourrait être de créer des millions de très court threads en cours d'exécution, chaque de ce qui aurait pu faire appel de Singleton.Exemple une fois).
Donc je pense qu'une double vérification de verrouillage est un mécanisme qui a une vraie place dans la très précis de la performance-les cas critiques, et puis tout le monde a grimpé sur le "c'est la bonne façon de le faire" boule de neige, sans vraiment penser à ce qu'il fait et s'il va être nécessaire dans le cas où ils utilisent.