Maison >Java >javaDidacticiel >Qu'est-ce que le mode de verrouillage à double vérification Java
J'ai rencontré un tel problème lors de la détection de code statique PMD sur le projet
Qu'est-ce que le mode de verrouillage à double vérificationLes objets partiellement créés peuvent être renvoyés par le modèle de verrouillage à double vérification lorsqu'il est utilisé en Java. Un JRE d'optimisation peut attribuer une référence à la variable baz. avant d'appeler le constructeur de l'objet vers lequel pointe la référence.
Remarque : avec Java 5, vous pouvez faire fonctionner le verrouillage à double vérification, si vous déclarez la variable comme volatile. renvoie un objet incomplètement initialisé. Certaines personnes peuvent douter du concept d'objets partiellement initialisés, veuillez continuer à analyser
<code>public static Singleton getSingleton() {<br> if (instance == null) { <br> synchronized (Singleton.class) {<br> if (instance == null) { <br> instance = new Singleton();<br> }<br> }<br> }<br> return instance ;<br>}</code>Nous voyons que instance == null est jugé à la fois à l'intérieur et à l'extérieur du bloc de code synchronisé. les threads peuvent entrer le jugement if en dehors du bloc de code synchronisé en même temps. Si aucun jugement nul n'est effectué à l'intérieur du bloc de code synchronisé, plusieurs instances peuvent être initialisées. Le problèmeCette façon d'écrire semble parfaite, mais elle est problématique, ou elle ne garantit pas qu'elle sera parfaite. La raison principale est que instance = new Singleton(); n'est pas une opération atomique.
<code>1.分配对象的内存空间<br>2.初始化对象<br>3.设置instance指向刚分配的内存地址<br>当instance指向分配地址时,instance是不为null的</code>
Cependant, entre les étapes 2 et 3, elle peut être réorganisée, ce qui fait que l'ordre de création des objets devient 1-3-2. Imaginez un scénario :
Thème A pour le. Créez l'objet Singleton pour la première fois, et l'ordre de création de l'objet est 1-3-2 ;
À ce moment, cette instance est jugée. == null, et on constate que l'instance n'est pas Not null.
Mais notez que l'instance n'a pas initialisé l'objet pour le moment et que le thread B renverra l'objet non initialisé. Des problèmes peuvent survenir lorsque le thread B utilise l'instance. Il s'agit du problème du verrouillage à double vérification.
Utiliser volatile
<code>public class Singleton{<br> private volatile static Singleton instance;<br> public static Singleton getSingleton() {<br> if (instance == null) { <br> synchronized (Singleton.class) {<br> if (instance == null) { <br> instance = new Singleton();<br> }<br> }<br> }<br> return instance ;<br> }<br>}</code>
<code>public class Singleton { <br> private static class SingletonHolder { <br> private static final Singleton INSTANCE = new Singleton(); <br> } <br> private Singleton (){} <br> public static final Singleton getInstance() { <br> return SingletonHolder.INSTANCE; <br> } <br>}</code>La méthode d'écriture actuellement recommandée consiste à utiliser des classes internes statiques, qui peuvent réaliser un chargement paresseux sans problèmes de sécurité des threads. Et cela réduit les frais généraux de synchronisation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!