如果我们仅使用Double Check Singleton模式的外部零检查,该怎么办



问题1:为什么在单线图案中,我们需要两个空检查?如果我们仅使用外部检查怎么办?

    if (instance == null) {
        synchronized (ABC.class) {
            // What if we remove this check?
            if (instance == null) {
                instance = new ABC();
            }
    }

问题2:以下各项有什么区别:

1:直接使用同步中的类名((

    public ABC getInstance() {
        if (instance == null) {
            // Difference here
            synchronized (ABC.class) {
                if (instance == null) {
                    instance = new ABC();
                }
            }
         }
         return instance;
    }

2:使用同步((>内部的静态最终对象
    private static final Object LOCK = new Object();
    .
    .
    public ABC getInstance() {
        if (instance == null) {
             // Difference here
             synchronized (LOCK) {
                if (instance == null) {
                    instance = new ABC();
                }
             }
         }
         return instance;
    }

3:使用 new Object((内部同步((

    if (instance == null) {
    // Difference here
         synchronized (new Object()) {
            if (instance == null) {
                instance = new ABC();
            }
        }
     }
  1. 删除内部无用检查可能会导致种族条件。想象以下情况:两个线程尝试同时获得对象的实例,因此他们都检查实例是否等于null并获得真实的答案,因此两个线程都会尝试创建对象的实例。由于此代码已同步,因此其中一个线程将输入代码的同步块,而另一个则等待锁定锁定。当第一个线程完成实例化和返回对象实例时,锁将被释放,第二个线程将执行同步块,因此它将创建一个新实例并返回它,因为它不知道它是以前创建的当它在等待它时。
  2. 使用类作为同步中的参数将生成静态锁。这意味着班级的所有实例都将共享锁。
  3. 使用对象作为同步的参数,如果您想用特定对象而不是类或此锁定同步块。这使您可以使用同一类中的不同锁具有不同的代码块。例如:

    Object o1 = new Object();
    Object o2 = new Object();
    synchronized(o1) {
        //your synchronized block
     }
    synchronized(o2){
        //other synchronized block
    }
    

在上一个代码示例中,block1和block2可以同时通过不同的线程执行,因为它们使用了其他锁定对象。如果您在两个代码块(即类(上使用相同的锁,则将块1被阻止,直到块2完成执行,而另一个方面。

最新更新