0
votes

Une autre question sur le "verrouillage à double vérification"

J'ai modifié un étui "normal" Singleton DCL Singleton selon "Efficace Java" # 83, comme ci-dessous.

public class Main {
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                System.out.println(MySystem.getInstance().getDate());
            }
        }.start();

        new Thread() {
            public void run() {
                System.out.println(MySystem.getInstance().getDate());
            }
        }.start();
    }
}


5 commentaires

Note latérale: Utilisation directe Nouvelle date () -> Date privée Date = nouvelle date (); Instende d'initialisation dans l'entrepreneur.


Parce que dans votre cas, vous prenez le verrouillage de niveau de classe.Elle partagera le même contexte. Si vous avez mis synchronisé le niveau de la méthode, tout fonctionne bien dans les deux cas.


Oui, l'exemple de "Java efficace" utilise la synchronisation de niveau de la méthode. Je ne peux pas vous attraper, voudriez-vous donner plus de détails sur le contexte? @Arunkumar


Vous savez que Le verrouillage double vérifié a été il y a longtemps prouvé qu'il était cassé modèle , non? Et que son livre blanc a été signé par Josh Bloch et d'autres luminaires Java ...


@Bohemian Oui, ma version Java est Java8, alors je pense que la version de DCL volatile est OK maintenant.


3 Réponses :


1
votes

La différence est la suivante:

MySystem.getInstance().getDate()


2 commentaires

Alors quelle est l'utilisation de synchronisée ici?


Ok, peut-être que ce n'était pas assez clair, je l'ai ajouté à ma réponse, merci



1
votes

OK, laissez-moi vous expliquer étape par étape. Fil d'un: mon == null. Thread b: mon == null, puis obtenir Sync, puis "instance = mon = nouveau mysystem ()" et renvoyez mon, ce qui n'est pas null. Fils A: Get Sync, puis "instance! = Null" et renvoyez mon, qui est NULL.

NPE, BANG! Donc, la "instance My =" avant la deuxième chèque est nécessaire. P>

Comment expliquer l'exemple dans "Java efficace"? P>

// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
private FieldType getField() {
    FieldType result = field;
    if (result == null) { // First check (no locking)
        synchronized(this) {
        if (field == null) // Second check (with locking)
            field = result = computeFieldValue();
        }
    }
    return result;
}


0 commentaires

1
votes

Vous obtenez NPE lorsque ce qui suit se produit:

public static MySystem getInstance() {
    MySystem my = instance;
    if (my == null) {
        synchronized (MySystem.class) {
            if (instance == null) {
                instance = new MySystem();
            }
        }
        my = instance;
    }
    return my;
}


0 commentaires