单例模式
思考
单例模式的实质是控制实例数量,当需要控制一个类的实例只能有一个时,使用单例模式。
使用场景
- java中缓存的实现:正是一种懒汉式的方式,查询的时候初始化缓存一次,之后访问每次访问初始化的缓存对象
- 数据库连接池:
- 线程池:
UML图
代码实现
饿汉式
- 结构
- 私有化无参构造函数
- 创建一个static修饰的对象
- 提供一个公共的static修饰的方法返回实例对象
- 优点
- 线程安全
- 空间换时间
//饿汉式
public class Singleton {
//2定义一个静态变量来存储创建好的类实例直接在这里创建类实例,由虚拟机来保证只会创建一次
private static Singleton instance = new Singleton();
//1:私有化构造方法,好在内部控制创建实例的数目
private Singleton(){
}
//3:这个方法需要定义成类方法,也就是要加static
public static Singleton getInstance(){
return instance;
}
public static void main(String[] args) {
for(int i=0;i<3;i++){
System.out.println(Singleton.getInstance());
}
}
}
懒汉式
- 结构
- 私有化构造方法
- 提供一个公共的static修饰的方法获取实例
- 双重NULL判断,加锁创建实例对象返回
- 实例对象使用volatile修饰
- 优点
- 节省空间
- 加锁同步后性能低于饿汉式
public class Singleton {
/**
* 对保存实例的变量添加volatile的修饰
*/
private volatile static Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance(){
//先检查实例是否存在,如果不存在才进入下面的同步块
if(instance == null){
//同步块,线程安全的创建实例
synchronized(Singleton.class){
//再次检查实例是否存在,如果不存在才真的创建实例
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
类级内部类实现单例
public class Singleton {
/**
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,
* 而且只有被调用到才会装载,从而实现了延迟加载
*/
private static class SingletonHolder{
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static Singleton instance = new Singleton();
}
/**
* 私有化构造方法
*/
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
枚举实现单例
java中的枚举其实是一种多例的实现,在枚举中只定义一个实例,那么就是最简单的一种单例模式
public enum Singleton {
uniqueInstance("test");
private Singleton(String name){
}
}