详解JAVA七种创建单例的方法

  


  

        公开课Singleton1 {//不能延迟加载占用内存耗费资源   私有静态Singleton1 Singleton1=new Singleton1 ();      公共静态Singleton1 getSingleton1 () {   返回singleton1;   }   }      之前      

可以保证多个线程下唯一实例,getSingleton1方法性能较高,但是无法进行懒加载。

  


  

        公开课Singleton2 {//延迟加载//多线程下不安全   私有静态Singleton2 singleton1=零;      公共Singleton2 getSingleton1 () {         如果(singleton1==null) {   singleton1=new Singleton2 ();   }   返回singleton1;   }   }      之前      

懒汉式解决了延迟加载和资源问题,但是多线程下存在线程不安全问题。

  


  

        公开课Singleton3 {//延迟加载//多线程下不安全   私有静态Singleton3 singleton1=零;//解决延迟加载多线程安全问题,但存在读操作,加锁问题,线程排队,写操作只有一次获取时需要排队等候问题   公共同步Singleton3 getSingleton1 () {      如果(singleton1==null) {   singleton1=new Singleton3 ();   }   返回singleton1;   }/*   等同方法前加锁   公共静态Singleton3 getSingleton1 () {   同步(Singleton3.class) {   如果(singleton1==null) {   singleton1=new Singleton3 ();   }   }      返回singleton1;   }   */}      之前      

解决延迟加载多线程安全问题,但存在读操作,加锁问题,线程排队,写操作(创建对象)只有一次,但是获取时需要排队等候问题

  


  

        公开课Singleton4 {//延迟加载   私有静态Singleton4 singleton1=零;//解决读操作多线程情况下排队获取问题,但是双重校验也存在一个问题,jvm重排序的问题下会存在空指针问题   公共静态Singleton4 getSingleton1 () {      如果(singleton1==null) {   同步(Singleton4.class) {   如果(singleton1==null) {   singleton1=new Singleton4 ();   }   }   }   返回singleton1;   }         }      之前      

解决读操作多线程情况下排队获取问题,但是双重校验也存在一个问题,jvm重排序的问题下会存在空指针问题

  

但存在一个问题,jvm指令重排序,jvm的即时编译器中存在指令重排序的优化。

  

1首先给singleton1分配内存
  2 Singleton4执行构造函数开辟空间
  3调用getSingleton1()方法创建对象
  JVM的即时编译器中存在指令重排序的优化

  

理想情况下jvm执行顺序是123也可能是132年,13在创建完对象后,再执行2返回零,此时就是空指针了。

  

  

挥发性关键字禁止JVM编译时指令重排序

        公开课Singleton5 {//延迟加载//不稳定的关键字禁止指令重排序//解决双重校验也存在一个问题,jvm重排序的问题下会存在空指针问题   私有静态稳定Singleton5 singleton1=零;         公共静态Singleton5 getSingleton1 () {      如果(singleton1==null) {   同步(Singleton5.class) {   如果(singleton1==null) {   singleton1=new Singleton5 ();   }   }   }   返回singleton1;   }         }      之前      


  

        公开课Singleton6 {//延迟加载//静态内部类静态的始终在jvm中存在一份   静态类单例{   私有静态Singleton6 singleton1=new Singleton6 ();   }         公共静态Singleton6 get () {   返回Singleton.singleton1;   }   }      之前      

        公开课Singleton7 {//枚举类型是线程安全构造方法只会被装载一次   私人enum集合{   单;      私人最终Singleton7 Singleton7;         单例(){   singleton7=new singleton7 ();   }         公共Singleton7 getSingleton7 () {   返回singleton7;   }      }//延迟加载   公共静态Singleton7 get () {   返回Singleton.Singleton.getSingleton7 ();   }//测试   公共静态void main (String [] args) {      IntStream。rangeClosed (100)。forEach(我→{   新线程(String.valueOf(我)){   @Override   公共空间run () {   System.out.println (Singleton7.get ());   }   } .start ();   });      }   }      

详解JAVA七种创建单例的方法