单例模式(Singleton Pattern)

概念

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一(主要减少内存占用)。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

可以总结出一条经验,单例模式主要解决的是一个全局使用的类,被频繁地创建与销毁,从而提升代码的整体性能;

简介

作用 :主要目的就是为了减少对象频繁创建而浪费内存

场景 :需要一个全局使用的类,枚举值等;

一般使用单例模式,就不会去考虑继承实现这一类的操作了,所有的具体逻辑实现都是在类的内部实现;

单例模式算是这些模式里面最好理解,使用起来也是最简单的一个模式了;
soeasy.gif

代码

工程目录

image.png

具体实现

懒汉式,线程不安全: 这种方式在多线程下面就没法使用了;

/**
 * 项目: question-study-improve
 * <p>
 * 功能描述: 懒汉式,线程不安全
 *
 * @author: WuChengXing
 * @create: 2021-07-13 00:26
 **/
public class LazyUnSafe {
    private static LazyUnSafe lazyUnSafe;

    private LazyUnSafe() {
    }

    public static LazyUnSafe getInstance() {
        if (lazyUnSafe != null) {
            return lazyUnSafe;
        }
        lazyUnSafe = new LazyUnSafe();
        return lazyUnSafe;
    }
}

懒汉 式,线程安全: 会有点性能的损耗,效率比较低,但是,但是会在第一次调用的时候初始化,可以避免内存的浪费;

/**
 * 项目: question-study-improve
 * <p>
 * 功能描述: 线程安全
 *
 * @author: WuChengXing
 * @create: 2021-07-13 00:28
 **/
public class LazySafe {
    private static LazySafe lazySafe;

    private LazySafe() {
    }

    public static synchronized LazySafe getInstance() {
        if (lazySafe != null) {
            return lazySafe;
        }
        lazySafe = new LazySafe();
        return lazySafe;
    }
}

饿汉式,线程安全 :这种方式比较常用,但容易产生垃圾对象。他会在类装载的时候就初始化,所以不管你用不用,都会占用内存空间;


/**
 * 项目: question-study-improve
 * <p>
 * 功能描述: 饿汉式
 *
 * @author: WuChengXing
 * @create: 2021-07-13 00:31
 **/
public class Hungry {
    private static Hungry hungry = new Hungry();

    private Hungry() {
    }

    public static Hungry getInstance() {
        return hungry;
    }
}

双重检查机制线程安全 :这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

/**
 * 项目: question-study-improve
 * <p>
 * 功能描述: 双重检查
 *
 * @author: WuChengXing
 * @create: 2021-06-19 12:16
 **/
public class DoubleCheckSingleton {

    private volatile static DoubleCheckSingleton doubleCheckSingleton;

    private DoubleCheckSingleton() {
    }

    public static DoubleCheckSingleton getInstance() {
        if (doubleCheckSingleton == null) {
            synchronized (DoubleCheckSingleton.class) {
                if (doubleCheckSingleton == null) {
                    doubleCheckSingleton = new DoubleCheckSingleton();
                }
            }
        }
        return doubleCheckSingleton;
    }

}

枚举类 :Effective Java作者推荐的枚举单例(线程安全)

/**
 * 项目: question-study-improve
 * <p>
 * 功能描述: 枚举单例
 *
 * @author: WuChengXing
 * @create: 2021-07-13 00:33
 **/
public enum EnumSingle {
    INSTANCE;
}

测试

/**
 * 项目: question-study-improve
 * <p>
 * 功能描述:
 *
 * @author: WuChengXing
 * @create: 2021-06-19 12:11
 **/
public class SingleTest {
    public static void main(String[] args) {

        DoubleCheckSingleton t1 = DoubleCheckSingleton.getInstance();
        System.out.println("t1对象 ==> " + t1 + ", 内存地址: ==> " + ObjectAddressUtil.getAddresses(t1));
        DoubleCheckSingleton t2 = DoubleCheckSingleton.getInstance();
        System.out.println("t2对象 ==> " + t2 + ", 内存地址: ==> " + ObjectAddressUtil.getAddresses(t2));
    }
}

结果:

t1对象 ==> com.simple.designpatterns.pattern23.creationtype.single.DoubleCheckSingleton@2530c12, 内存地址: ==> 0x7164aa1a0
t2对象 ==> com.simple.designpatterns.pattern23.creationtype.single.DoubleCheckSingleton@2530c12, 内存地址: ==> 0x7164aa1a0