设计模式:单例模式(singleton)

2022年9月28日11:13:22

前言

单例模式:

  1. 是在整个软件生命周期中,值存在一个实例。使用单例模式可以提供系统性能。属于创建者
  2. 使用场景:频繁创建和销毁的对象、创建对象耗时过长或耗费资源过多的对象。

一、单例代码实现

1.主程序代码

代码如下(示例):

/**
 * 保证整个软件系统中,对某个类智能存在一个对象实例
 * 属于创建者模式
 */publicclassSingletonClient{/**
     * 1. 饿汉式(静态常量)
     * 2. 饿汉式(静态代码块)
     * 3. 懒汉式(线程安全、同步方法)
     * 4. 双重检查
     * 5. 静态内部类
     * 6. 枚举
     */publicstaticvoidmain(String[] args){staticFinal();staticCode();synchronizedMethod();synchronizedCode();staticInsideClass();enumInstance();}//枚举publicstaticvoidenumInstance(){SingletonEnum singleton1=SingletonEnum.INSTANCE;SingletonEnum singleton2=SingletonEnum.INSTANCE;System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//饿汉式(静态常量)publicstaticvoidstaticFinal(){SingletonStaticFinal singleton1=SingletonStaticFinal.getInstance();SingletonStaticFinal singleton2=SingletonStaticFinal.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//饿汉式(静态代码块)publicstaticvoidstaticCode(){SingletonStaticCode singleton1=SingletonStaticCode.getInstance();SingletonStaticCode singleton2=SingletonStaticCode.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(同步方法)publicstaticvoidsynchronizedMethod(){SingletonSynchronizedMethod singleton1=SingletonSynchronizedMethod.getInstance();SingletonSynchronizedMethod singleton2=SingletonSynchronizedMethod.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(同步代码块)publicstaticvoidsynchronizedCode(){SingletonSynchronizedCode singleton1=SingletonSynchronizedCode.getInstance();SingletonSynchronizedCode singleton2=SingletonSynchronizedCode.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}//懒汉式(静态内部类)publicstaticvoidstaticInsideClass(){SingletonStaticInsideClass singleton1=SingletonStaticInsideClass.getInstance();SingletonStaticInsideClass singleton2=SingletonStaticInsideClass.getInstance();System.out.println("singleton1 hash code =  "+ singleton1.hashCode());System.out.println("singleton2 hash code  = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2  is "+(singleton1== singleton2));}

2.静态常量(static final)

代码实现

/**
 * 静态常量:单例
 * instance:在类装载到方法区时,静态常量会自动创建。避免了多线程.
 * 不好的地方是如果不使用,就会浪费内存。
 */publicclassSingletonStaticFinal{privatestaticfinalSingletonStaticFinal  instance=newSingletonStaticFinal();/**
     * 私有化是为了防止,外部类创建。
     */privateSingletonStaticFinal(){}publicstaticSingletonStaticFinalgetInstance(){return instance;}}

3. 静态代码块(static code)

代码如下(示例):

/**
 * 静态代码块:单例
 * instance:在类装载到方法区时,会执行静态代码块。避免了多线程.
 * 不好的地方是如果不使用,就会浪费内存。
 */publicclassSingletonStaticCode{privatestaticSingletonStaticCode instance;//静态代码块static{
        instance=newSingletonStaticCode();}/**
     * 私有化是为了防止,外部类创建。
     */privateSingletonStaticCode(){}publicstaticSingletonStaticCodegetInstance(){return instance;}}

4. 同步静态方法(synchronized static method)

代码如下(示例):

/**
 * 同步静态方法:单例
 * instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.
 * 需要添加同步(synchronized)方法
 * 只有在使用的时候创建,避免浪费内存。
 * 出现问题:效率过低,每次调用都是同步
 */publicclassSingletonSynchronizedMethod{privatestaticSingletonSynchronizedMethod instance;/**
     * 私有化是为了防止,外部类创建。
     */privateSingletonSynchronizedMethod(){}/**
     * 每次执行,都是同步执行。导致效率过低
     */publicsynchronizedstaticSingletonSynchronizedMethodgetInstance(){if(instance==null){
            instance=newSingletonSynchronizedMethod();}return instance;}}

5. 双重检查(double check)

代码如下(示例):

/**
 * 双重检查:单例
 * instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.
 * 需要添加同步(synchronized)方法
 * 只有在使用的时候创建,避免浪费内存。
 * 推荐使用
 */publicclassSingletonSynchronizedCode{privatestaticvolatileSingletonSynchronizedCode instance;/**
     * 私有化是为了防止,外部类创建。
     */privateSingletonSynchronizedCode(){}//双重检查,publicstaticSingletonSynchronizedCodegetInstance(){if(instance==null){synchronized(SingletonStaticCode.class){//如果不检查,多线程情况下会创建多个实例if(instance==null){
                    instance=newSingletonSynchronizedCode();}}}return instance;}}

6. 静态内部类(static inside class)

代码如下(示例):

/**
 * 静态内部类:单例
 * 推荐使用
 */publicclassSingletonStaticInsideClass{privatestaticSingletonStaticInsideClass instance;static{
        instance=newSingletonStaticInsideClass();}/**
     * 私有化是为了防止,外部类创建。
     */privateSingletonStaticInsideClass(){}privatestaticclassSignleton{privatestaticfinalSingletonStaticInsideClass INSTANCE=newSingletonStaticInsideClass();}publicstaticSingletonStaticInsideClassgetInstance(){//当静态方法调用是,才会加载内部静态类。//而内部静态类,在加载到方法区的时候会创建静态常量,避免多线程创建。returnSignleton.INSTANCE;}}

总结

推荐使用:

  1. 双重检查
  2. 静态内部类
  3. 枚举:还能有效防止反序列化。
  • 作者:swg321321
  • 原文链接:https://blog.csdn.net/swg321321/article/details/125667121
    更新时间:2022年9月28日11:13:22 ,共 4940 字。