单例模式确保某个类只有一个实例,并且自行实例化并向整个系统提供这个实例。java
饿汉式
public class Singleton{ private static Singleton instance=new Singleton(); //私有构造器,防止被屡次new建立 private Singleton(){} public static Singleton getInstance(){ return instance; } }
静态内部类
public class Singleton{ //私有构造器,防止被屡次new建立 private Singleton(){} //把instance的实例放到静态类内部 private static class SingletonInstance{ private static final Singleton instance=new Singleton(); } //调用getInstance方法时加载静态内部类 public static Singleton getInstance(){ return SingletonInstance.instance; } )
双重检查(推荐)
public class Singleton{ //volatile关键字确保多个线程正确地处理instance变量 private volatile static Singleton instance; //私有构造器,防止被屡次new建立 private Singleton(){} piblic static Singleton getInstance(){ //第一次检查 if(instance==null){ synchronized(Singleton.class){ //第二次检查 if(instance==null){ instance=new Singleton(); } } } return instance; } }
为何instance须要用volatile修饰?
由于new Singleton()可能会发生重排序,具体能够分为三个步骤:
一、为对象分配内存
二、初始化对象
三、让instance指向内存地址
这种状况下可能会发生重排序,也就是变成1——>3——>2(单线程下并无改变结果,因此这是容许的,可是多线程下可能会返回未初始化的instance),所以须要volatile禁止重排序多线程