Java “怎么做?”;“静态”;保证属性中只有一个类实例?

Java “怎么做?”;“静态”;保证属性中只有一个类实例?,java,thread-safety,singleton,Java,Thread Safety,Singleton,我要说明的最好的例子是单例模式 在这段代码中,引入了静态变量,以避免同步到获取指向Singleton实例的指针的任何需要。有办法知道这是怎么发生的吗?静态是如何实现的?在jvm加载类的过程中加载类的静态属性,因为这在运行时只发生一次。可以保证只创建一次静态属性。静态字段在加载类时初始化,以防止多个线程同时初始化它们。有关如何工作的详细信息,请参阅。在您的代码中,在类加载之后,没有其他任何东西会设置static字段的值,因此它将拥有的唯一值是在类加载时实例化的值 通过标记字段final,您可以/应

我要说明的最好的例子是单例模式


在这段代码中,引入了静态变量,以避免同步到获取指向Singleton实例的指针的任何需要。有办法知道这是怎么发生的吗?静态是如何实现的?

在jvm加载类的过程中加载类的静态属性,因为这在运行时只发生一次。可以保证只创建一次静态属性。

静态字段在加载类时初始化,以防止多个线程同时初始化它们。有关如何工作的详细信息,请参阅。在您的代码中,在类加载之后,没有其他任何东西会设置
static
字段的值,因此它将拥有的唯一值是在类加载时实例化的值

通过标记字段
final
,您可以/应该更清楚地说明这一点(以及代码更改方面的更多未来证据)。根据JLS,这可能也是全线程安全性所必需的(尽管实际上是这样)



轻微的自我批评:上面段落中的“类加载”实际上是“类实例化”,这实际上是JLS定义的加载后发生的一个步骤。我将其称为“加载”,以使其更明显地区别于静态字段的实例化。尽管类加载只是类初始化的一个步骤(如JLS 12.4中的定义,上面的链接),但整个过程有时会缩短为通用术语中的“类加载”。

我仍然会添加
final
,以确保安全发布。它也是在类加载系统中实现的——类的任何静态初始化代码都必须在类加载时运行,这在第一次执行代码时发生。类加载器可能负责适当的同步,以确保没有线程可以看到半初始化的类。。。请参见此处选择的答案:这会有所帮助。请记住,如果单例具有可变状态,则在构造后更改此状态确实需要同步或类似的线程安全构造。
public class Singleton {     
     private static Singleton instance = new Singleton();     

     private Singleton() {     
     }     

     public static Singleton getInstance() {
          return instance;    
     } 
}