单例模式
单例模式是一种常见的创建型设计模式,用于限制一个类被多次实例化。在单例模式中,一个类只能由一个对象实例化存在,并且该对象可以被系统中的其他类访问。单例模式保证系统中只有一个对象实例存在,从而避免了资源的浪费和冲突。
1、饿汉模式
1.1、简介
是一种线程安全的模式,在类加载的时候就会创建对象;
public class SingletonClass{
private static final SingletonClass singletonClass = new SingletonClass();
public SingletonClass() {}
public static SingletonClass getIntance(){
return singletonClass ;
}
}
2、懒汉模式
2.1、简介
懒汉模式是在调用getInstnce()方法的时候才会创建对象,在多线程模式下是不安全的。单例模式可以使用多种不同的实现方式,包括懒汉式、饿汉式、双重检查锁定、静态内部类、枚举等。每种实现方式都有其优缺点,需要根据具体的需求场景来选择合适的实现方式。
2.2、如下
2.2.1、饿汉模式
public class SingletonClass{
private static SingletonClass singletonClass = null;
private SingletonClass() {}
public static SingletonClass getInstance(){
if (singletonClass == null) {
singletonClass = new SingletonClass();
}
return signleClass;
}
}
2.2.2、懒汉模式(不安全)
public class SingletonClass {
private static SingletonClass singletonClass = null;
private SingletonClass(){}
public static SingletonClass getInstance(){
return singletonClass = new SingletonClass();
}
}
该懒汉模式没有考虑安全问题,在多线程情况下可能会创建多个实例。
懒汉模式(安全)
public class SingletonClass{
private static SingletonClass singletonClass = null;
private SingletonClass() {}
public static synchronized SingletonClass getInstance(){
if (singletonClass == null) {
singletonClass = new SingletonClass();
}
return singletonClass;
}
}
这个是线程安全的,因为在方法getInstance()上添加了synchronized关键字,该关键字保证了在同一时刻只能由一个线程访问这个方法。
2.2.3、双重检查锁定
public class SingletonClass{
private static SingletonClss singletonClass = null;
private SingletonClass() {}
public static SingletonClass getInstance(){
if (singletonClass == null) {
synchronized (SingletonClass.class) {
if (singletonClass == null){
singletonClass = new SingletonClass();
}
}
}
return singletonClass ;
}
}
通过加锁和双重的判断方式实现了懒加载的线程安全。
2.2.4、静态内部类
使用静态内部类实现单例模式,是具有线程安全。静态内部类在加载的时候只会被加载一次,且静态内部类在类加载的时候不会被初始化,只有在调用静态内部类的时候才会被实例化,且静态初始化只会执行一次,因此是线程安全的。并且静态内部类是私有的,因此外部无法访问,也保证单例的唯一性。
public class SingletonClass {
private SingletonClass () {}
private static class SingletonHandle{
private static final SingletonClass singletonClass = new SingletonClass ();
}
public static SingletonClass getInstance() {
return SingletonHandle.singletonClass;
}
}
2.2.5、枚举单例模式
枚举常量只会被初始化一次,因此可以实现单例模式,枚举单例模式是一种更加简洁的实现方式。Java虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次。
public enum SingletonClass{
INSTANCE;
private SingletonClass singletonClass = null;
private SingletonClass () {
singletonClass = new SingletonClass ();
}
public SingletonClass getInstance() {
return singletonClass;
}
}
私有的构造函数,保证了外部无法直接实例化该类,只能通过getInstance()方法获取该类的唯一实例。
静态变量singletonClass是该类的唯一实例;
静态的方法getInstance()是获取该类的唯一实例。
单例模式适用于全局唯一实例的场景,比如全局配置管理,缓存管理,日志管理,全局对象的创建,资源共享等。