单例模式是设计模式中最简单的一个模式,也是常被忽略的一个设计模式。如果不对单例模式进行一次认真的研究,真不见得能写出让自己满意的一种实现,即考虑岛安全和效率。单例模式有两种实现方式---饿汉式和懒汉式。
饿汉式单例模式就是在程序启动时就完成了初始化,这种实现比较简单
//饿汉式
public class Singleton {
private static Singleton instance = new Singleton(); //1,单例对象的引用
private Singleton() {} //2,声明构造函数私有
public static Singleton getInstance() { //3,获取单例对象方法
return instance;
}
}
饿汉式中的单例对象instance是在对类Singleton初始化中创建的,在多线程环境下也是安全的。因为jvm在对类Singleton初始化时就考虑了多线程并发带来的问题。
懒汉式单例模式是在第一次使用到单例对象来创建的,在单线程环境下下面的代码是ok的
//懒汉式
public class Singleton {
private static Singleton instance = null; //1,单例对象的引用
private Singleton() {} //2,声明构造函数私有
public static Singleton getInstance() { //3,获取单例对象方法
if (instance == null) { //4,判断是否为null
instance = new Singleton(); //5,创建单例对象
}
return instance;
}
}
//懒汉式
public class Singleton {
private static Singleton instance = null; //1,单例对象的引用
private Singleton() {} //2,声明构造函数私有
public static synchronized Singleton getInstance() { //3,获取单例对象方法
if (instance == null) { //4,判断是否为null
instance = new Singleton(); //5,创建单例对象
}
return instance;
}
}
//懒汉式---双重检查锁
public class Singleton {
private static Singleton instance = null; //1,单例对象的引用
private Singleton() {} //2,声明构造函数私有
public static Singleton getInstance() { //3,获取单例对象方法
if (instance == null) { //4,第一次判断instance是否为null
synchronized (Singleton.class) { //同步块
if (instance == null) { //5,第二次判断instance是否为null
instance = new Singleton(); //6,创建单例对象
}
}
}
return instance;
}
}
memory = allocate(); //1,分配对象的内存空间
ctorInstance(memory); //2,初始化对象
instance = memory; //3,设置instance指向刚才分配的内存空间
//懒汉式---双重检查锁
public class Singleton {
private static volatile Singleton instance = null; //1,单例对象的引用
private Singleton() {} //2,声明构造函数私有
public static Singleton getInstance() { //3,获取单例对象方法
if (instance == null) { //4,判断是否为null
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
对没有看错,就是把instance生命为volatile变量即可。java内存模型会禁止对volatile变量的写与它之前的任何指令进行重排序。这样一个完美的单例模式就被实现出来了。除了双重检查锁,还有一种实现方式就是使用嵌套类,就是通过利用jvm对java类的初始化的同步来完成的,代码如下
public class InstanceHoder {
public static class Singleton {
private static Singleton singleton = new Singleton();
public static Singleton getInstance() {
return singleton;
}
}
}