一、什么是单例模式
单例模式是 Java 中相对简单的一种设计模式。为了节省内存资源、保证数据内容的一致性,对某些类需要或者只能创建一个实例,这就是所谓的单例模式。
单例模式有 3 个特点:
1.单例类只有一个实例对象;
2.该单例对象必须由单例类自行创建;
3.单例类对外提供一个访问该单例的全局访问点。
二、 单例模式的实现
第 1 种:饿汉式单例
类一旦加载就创建一个单例,这种方式比较常用。执行效率高,支持多线程但相对的却又浪费了内存空间。
public class Singleton01 {
private static final Singleton01 instance = new Singleton01(); //在程序启动时就将创建单例
private Singleton01() { //private修饰,禁止外部调用构造方法
}
public static Singleton01 getInstance() { //只能通过getInstance()获取该类的唯一实例
return instance;
}
}
第2种:懒汉式单例,线程不安全
最基本最简单的实现方式,但不支持多线程,在高并发环境下容易生成多个实例。
public class Singleton02 {
private static Singleton02 instance;
private Singleton02(){}
public static Singleton02 getInstance() { //在获取实例时进行判断,如果还没有实例就新生成实例
if (instance == null){
instance = new Singleton02();
}
return instance;
}
}
第3种:懒汉式单例,线程安全
在之前的基础上加锁实现线程安全,但是锁代码块太大,影响效率,毕竟大部分的情况下是不需要同步的
public class Singleton03 {
private static Singleton03 instance;
private Singleton03() {
}
public static synchronized Singleton03 getInstance() { //增加synchronized关键字,实现线程安全
if (instance == null) {
instance = new Singleton03();
}
return instance;
}
}
第4种:懒汉式单例,双重校验锁
再次在之前的基础上进行双重判空,减小锁代码块的大小,大大提高效率
public class Singleton04 {
private volatile static Singleton04 singleton;
private Singleton04() {
}
public static Singleton04 getSingleton() { //减小锁代码块,只有第一次创建实例的时候才进入锁,优化了后续调用单例的速度
if (singleton == null) {
synchronized (Singleton04.class) {
if (singleton == null) {
singleton = new Singleton04();
}
}
}
return singleton;
}
}
第5种:静态内部类单例
Singleton 类被装载了,其静态内部类没有被初始化,只有通过显式调用getInstance 方法时,才会显式装载其静态内部类,从而实例化。算是一种延迟加载单例的方式。
public class Singleton05 {
private static class SingletonHolder { //静态内部类进行项目实例化
private static final Singleton05 INSTANCE = new Singleton05();
}
private Singleton05() {}
public static final Singleton05 getInstance() { //调用时才会实例化静态内部类
return SingletonHolder.INSTANCE;
}
}
第6种:枚举实现单例
《effective java》作者亲自下场。单元素的枚举类型或许是实现单例模式的最佳方法
但平时实际运用较少,就不不细说了
public enum Singleton06 {
INSTANCE;
public Singleton06 getInstance() {
return INSTANCE;
}
}