Does java have a static sequential initialization failure?

A recent problem here is to have the following code (and similar) to implement a singleton without synchronization

public class Singleton {
    private Singleton() {}
    private static class SingletonHolder { 
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

Now, I want to understand what this is for Because the instance is static final, it is established long before any thread calls getInstance (), so synchronization is not required

Synchronization is required only when two threads attempt to call getInstance () at the same time (the method is constructed on the first call, not "static final")

So my question is basically: why do you like to build singles lazily?

public class Singleton {
    private Singleton() {}
    private static Singleton instance = null;
    public static synchronized Singleton getInstance() {
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
}

My only idea is that using the static final method may introduce sorting problems, such as C static initialization sequence failure

First, does Java actually have this problem? I know that the order in a class is completely specified, but it ensures a consistent order between classes in some way (such as using a class loader)?

Secondly, if the orders are consistent, why is lazy construction scheme beneficial?

Solution

Incomplete It is built when the singletonholder class is initialized, which occurs when getInstance is called for the first time The class loader has a separate locking mechanism, but no further locking is required after loading the class, so the scheme only needs enough locking to prevent multiple instantiation

Java does have a problem, that is, the class initialization cycle may cause some classes to observe the static final of another class before initialization (technically before all static initialization blocks run)

consider

class A {
  static final int X = B.Y;
  // Call to Math.min defeats constant inlining
  static final int Y = Math.min(42,43);
}

class B {
  static final int X = A.Y;
  static final int Y = Math.min(42,43);
}

public class C {
  public static void main(String[] argv) {
    System.err.println("A.X=" + A.X + ",A.Y=" + A.Y);
    System.err.println("B.X=" + B.X + ",B.Y=" + B.Y);
  }
}

Run C print

A.X=42,A.Y=42
B.X=0,B.Y=42

But in your idiom, there is no loop between helper and singleton, so there is no reason to prefer lazy initialization

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>