单例模式是设计模式中最简单的一种设计模式。适用的场景是一个类有且仅有一个实例,并为它提供一个全局访问点。单例模式不允许使用new关键字创建对象,只能由单例对象自己创建一个实例,确保该类的实例有且仅有一个。
用法:
1、私有的无参构造函数。
2、该类自己创建一个实例
3、提供公共接口返回该类的实例
方式1(饿汉式):
/**
* 饿汉式
*/
public class Singleton {
//类加载的时候就创建实例
private static Singleton singleton = new Singleton();
//使无参构造函数为private,防止外部创建对象
private Singleton() {}
public static Singleton getInstance() {
return singleton;
}
}
方式2(懒汉式):
/**
* 懒汉式
*/
public class Singleton {
private static Singleton singleton = null;
//使无参构造函数为private,防止外部创建对象
private Singleton() {}
public static Singleton getInstance() {
//如果实例没有被创建,就执行创建;如果已经创建,直接返回
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
方式3(懒汉式,多线程环境下):
/**
* 懒汉式,多线程环境下
*/
public class Singleton {
private volatile static Singleton singleton = null;
//使无参构造函数为private,防止外部创建对象
private Singleton() {}
public static Singleton getInstance() {
if(singleton == null) {
synchronized (Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
其中singleton被定义为volatile,volatile能够使该变量在多线程的环境下获得正确的值 。其中volatile有两种特性:第一是保证此变量的可见性(该类型变量对所有线程可见);第二是禁止指令重排序。
synchronized代码块 在此处保证了singleton在创建的时候是安全且正确的。synchronized是排它锁,每次只有一个线程能够进入代码块,其它线程处于阻塞状态,只有当前线程释放了锁其它线程才有机会进入代码块,从而保证了只会创建一个singleton实例。