设计模式之单例模式
单例设计模式:
- 单例顾名思义只包含一个对象被称为单例的特殊类。
- 通过单例模式可以保证系统中,应用该模式的类只有一个对象实例。
使用场景
- 业务系统全局只需要一个对象实例,比如redis连接对象、发号器等
- Spring IOC容器中的bean默认就是单例
- spring boot中的controller、service、dao层中通过@autowire的依赖注入对象默认都是单例的
分类
- 懒汉:就是所谓的懒加载,延迟创建对象
- 饿汉:与懒汉相反,提前创建好对象
实现步骤
- 私有化构造函数
- 提供获取单例的方法
懒汉方式实现的几种方式如下:
public class SingletonLazy{
//private static SingletonLazy instance;
/**
*构造函数私有化
*/
private SingletonLazy(){}
/**
*单例对象的方法
*/
public void process(){
system.out.printIn("方法调用成功");
}
/**
*第一种方式
*对外暴露一个方法获取类的对象
*多线程下存在安全问题,线程不安全
*/
/*
public static Singletonlazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
*/
/**
*第二种方式
*通过synchronized加锁保证单例
*采用synchronized对方法加锁有很大的性能开销
*解决办法:锁粒度不要这么大
*/
/*
public static synchronized Singletonlazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
*/
/**
*第三种方式
*DCL 双重检查锁定,在多线程情况下保存高性能
*不一定安全,因为instance = new SingletonLazy();并不是原子性操作
*1、分配空间给对象
*2、在空间内创建对象
*3、将对象赋值给引用instance
*根据JVM的指令重排特性,假如线程按照1->3->2顺序,会把值写进主内存,其他线程就会读到instance最新的值,但是这个是不完全的对象
*/
/*
public static Singletonlazy getInstance(){
if(instance == null){
synchronized(SingletonLazy.class){
if(instance == null){
instance = new SingletonLazy();
}
}
}
return instance;
}
*/
/**
*volatile是java提供的关键字,它具有可见性和可序性
*指令重排是JVM对语句执行的优化,只要语句间没有依赖,那JVM就有权对语句进行优化
*禁止指令重排
*/
private static volatile SingletonLazy instance;
public static Singletonlazy getInstance(){
//第一重检查
if(instance == null){
//A、B线程锁定
synchronized(SingletonLazy.class){
//第二重检查
if(instance == null){
instance = new SingletonLazy();
}
}
}
return instance;
}
}
饿汉的实现方式比较简单如下:
public class SingletonHungry{
private static SingletonHungry instance = new SignletonHungry();
//私有化构造函数
private SingletonHungry(){}
public static SingletonHungry getInstance(){
return instance;
}
/**
*单例对象的方法
*/
public void process(){
system.out.printIn("方法调用成功");
}
}
饿汉方式的优缺点:
- 优点;实现简单,没有多线程同步问题
- 缺点:不管有没有使用,instance对象一直占用着这段内存
懒汉与饿汉如何选择:
- 如果对象不大,且创建不复杂,直接用饿汉的方式
- 其他情况则更多采用懒汉实现方式
JDK源码里面的单例模式
- JDK中Runtime类 饿汉方式
- JDK中Desktop类 懒汉方式