学无止境,只有多学习才能进步
前述
单例模式是23中设计模式之一,在我们java中也是很多地方用到,枚举类就是单例模式(ENUM),spring bean的作用域也是默认的singlton(单例模式)。
OOP七大原则
在我们学习单例模式之前,我们需要先了解oop的七大原则
开闭原则:对扩展开放,对修改关闭
里氏替换原则:继承要保证所有父类的特性在子类依然成立
依赖倒置原则:面向接口编程,不要面向实现编程
单一职责原则:控制类的粒子度,降低对象的耦合,提高内聚性
接口隔离原则:要为所有类创建专门的接口
迪米特原则:直接和你朋友沟通,不要和陌生人说话
合成复用原则:尽量能用组合或者聚合关系完成,其次考虑使用继承实现
单例模式
饿汉式
什么是饿汉式?
单例直接创建,这种情况下是线程安全,但也会出现一个问题就是不管用不用都会导致单例的创建,会导致资源的浪费
public class Singleton {
private Singleton(){
}
// 直接创建对象
private static Singleton singleton = new Singleton();
// 获取对象实例
public static Singleton getIntance(){
return singleton;
}
// 验证是否是单例
public static void main(String[] args) {
Singleton intance = Singleton.getIntance();
Singleton intance1 = Singleton.getIntance();
System.out.println(intance);
System.out.println(intance1);
}
}
输出结果:
懒汉式
什么是懒汉式?
懒汉式是我不会直接去创建,而是你用的时候再去创建,这个有明显的好处就是避免资源的浪费,但是在多线程情况下会不安全。
public class Singleton {
private Singleton(){
}
// 直接创建对象
private static Singleton singleton;
// 获取对象实例
public static Singleton getIntance(){
// 当实例为空的时候 才去创建
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
// 验证是否是单例
public static void main(String[] args) {
Singleton intance = Singleton.getIntance();
Singleton intance1 = Singleton.getIntance();
System.out.println(intance);
System.out.println(intance1);
}
}
运行结果:
DCL懒汉式
这个是在懒汉式的基础上进行双重锁检测,以保证线程的安全性
public class Singleton {
private Singleton(){
System.out.println(Thread.currentThread().getName());
}
// 直接创建对象 volatile是为了保证原子性
private volatile static Singleton singleton;
// 获取对象实例
public static Singleton getIntance(){
if(singleton == null){
// 锁住singleton类
synchronized (Singleton.class){
// 当实例为空的时候 才去创建
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
// 验证是否是单例
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread(()->{
Singleton.getIntance();
}).start();
}
}
}
运行结果:
如果还是看不懂或者不太了解推荐去看下狂神的视频讲解的很详细
链接: link