文章目录
一、什么是单例模式
保证一个类仅能创建一个对象实例,并对外提供统一的获取对象实例的方法。
二、使用场景
1、节约系统资源
可以避免过多的对象创建和销毁带来的系统资源消耗。
2、提供对某类仅需要唯一实例的访问控制
有些类在我们实际的项目运用过程中,仅仅只需要实例化一个对象。比如我们在项目中用的Service类仅仅需要一个实例,就可以满足我们的功能需求。
三、案例:常见的五种单例模式实现方式
1、饿汉式(线程安全,调用效率高,但是,不能延时加载。)
public class SingletonDemo1 {
private static SingletonDemo1 instance = new SingletonDemo1();//类初始化时,立即加载这个对象。
private SingletonDemo1() {
}
//方法没有同步,调用效率高
public SingletonDemo1 getInstance() {
return instance;
}
}
2、懒汉式(线程安全,调用效率低。但是,可以延时加载。真正用的时候才加载)
问题:
资源利用率高。但是,每次调用getInstance()方法都要同步,并发效率低。
public class SingletonDemo2 {
//类初始化时,不初始化这个对象(延时加载,真正用的时候在创建)
private static SingletonDemo2 ;
private SingletonDemo2() {
}
//方法同步,调用效率低
public static synchronized SingletonDemo2 getInstance() {
if(s == null) {
s = new SingletonDemo2();
}
return s;
}
}
其他:
1、双重检测锁式
这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步创建了以后就没有必要了。
package GOF.创建者模式;
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
3、静态内部类式(线程安全,调用效率高,但是可以延时加载)
public class SingletonDemo4 {
private SingletonDemo4() {
}
private static class SingletonClassInstance {
private static final SingletonDemo4 instance = new SingletonDemo4();
}
public static SingletonDemo4 getInstance() {
return SingletonClassInstance.instance;
}
}
要点:
(1)、外部类没有static属性,则不会像饿汉式那样立即加载对象。
(2)、只有真正调用getInstance(),才会加载静态内部类。加载类时是线程安全的。instance是static final类型,保证了内存只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性。
(3)、兼备了并发高效调用和延迟加载的优势。
4、枚举单例(线程安全,调用效率高,不能延时加载)
public enum SingletonDemo5 {
INSTANCE;
}