单例设计模式概述
单例设计模式:运用单例设计模式的类,在系统中它的对象永远只有一个。
适用场景:当我们希望该类的对象只有一个时,我们就可以使用单例模式,这样可以节约内存,提升性能。
饿汉式单例设计模式:
饿汉式单例设计模式特点:不管你有没有使用这个对象,它都会产生一个对象。为了达到这个目的,我们可以用private final static来修饰一个成员变量,然后用这个变量来存储唯一对象,再将构造器私有化,最后设计一个方法来返回这个唯一对象。
懒汉式单例设计模式:
懒汉式单例设计模式特点:等我们需要使用这个对象的时候,才会创建这个唯一对象。为了达到这个目的,我们可以用private static来修饰一个成员变量,再将构造器私有化,最后设计一个方法来返回这个唯一对象,在方法中,先判断成员变量的值是否为null,如果为null,则创建一个对象赋值给这个变量,如果不为null,则直接返回这个变量。
/**
* @description: 饿汉式单例设计模式
* @author: Murphy
* @date: 2020/6/262:05 上午
*/
public class Hungry {
private final static Hungry hungry = new Hungry();
private Hungry() {
}
public static Hungry getHungry() {
return hungry;
}
}
/**
* @description: 懒汉式单例设计模式
* @author: Murphy
* @date: 2020/6/262:10 上午
*/
public class Lazy {
private static Lazy lazy;
private Lazy() {
}
public static Lazy getLazy() {
if (lazy != null) {
return lazy;
}
lazy = new Lazy();
return lazy;
}
}
/**
* @description: 测试类
* @author: Murphy
* @date: 2020/6/262:07 上午
*/
public class Demo {
public static void main(String[] args) {
Hungry hungry1 = Hungry.getHungry();
Hungry hungry2 = Hungry.getHungry();
System.out.println(hungry1 == hungry2);
Lazy lazy1 = Lazy.getLazy();
Lazy lazy2 = Lazy.getLazy();
System.out.println(lazy1 == lazy2);
}
}
两种单例设计模式的比较
从线程安全上:饿汉式单例设计模式天生就是线程安全的,可以直接用于多线程而不出现问题。懒汉式单例设计模式是线程不安全的,在高并发环境下可能出现多个实例。
从资源加载和性能上:饿汉式单例设计模式在类创建的同时就实例化一个对象出来,不管之后会不会用到这个单例,都会占据一定的内存,但是相应的,第一次调用的时候速度也会更快,因为其资源已经初始化完成。懒汉式单例设计模式因为在第一次使用该单例时才会实例化对象出来,所以第一次调用,性能上会有些延迟,之后就和饿汉式一样了。
懒汉式单例设计模式的优化
为了使懒汉式单例设计模式变得线程安全,我们可以使用静态内部类的方式优化代码。
/**
* @description: 懒汉式单例设计模式
* @author: Murphy
* @date: 2020/6/262:10 上午
*/
public class Lazy {
private Lazy() {
}
private static class LazyHolder {
private final static Lazy LAZY = new Lazy();
}
public static Lazy getLazy() {
return LazyHolder.LAZY;
}
}