代码改变世界

徒手撸设计模式-单例模式

2022-07-06 17:21  hikoukay  阅读(41)  评论(0编辑  收藏  举报

概念

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

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

参考连接: https://www.runoob.com/design-pattern/singleton-pattern.html

代码案例

公共类

public final class StFlag {
    public StFlag() {
    }
    /**
     * 饿汉式
     */
    public static final String HUNDER="HUNDER";
    /**
     * 双重检验锁
     */
    public static final String DCL="DCL";
    /**
     * 懒汉式非安全
     */
    public static final String LAZYUNSAFE="LAZYUNSAFE";
    /**
     * 懒汉式安全
     */
    public static final String LAZYSAFE="LAZYSAFE";
    /**
     * 静态内部类
     */
    public static final String STATICINNER="STATICINNER";

}

 

五种单例模式

DCL

/**
 * double check locking 双重检验锁
 */
@Slf4j
public class SingletonDCL {
    //创建 SingleObject 的一个对象
    private volatile static SingletonDCL instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonDCL(){}

    //获取唯一可用的对象
    public static SingletonDCL getInstance(){
        if (instance ==null){
            synchronized (SingletonDCL.class){
                if (instance ==null){
                    instance=new SingletonDCL();
                }
            }
        }
        return instance;
    }

    public void showMessage(){
        log.info("DCL say Hello World!=========="+instance.hashCode());
    }
}

 

饿汉式

/**
 * 饿汉式
 */
@Slf4j
public class SingletonHunger {
    //创建 SingleObject 的一个对象
    private static SingletonHunger instance = new SingletonHunger();

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonHunger(){}

    //获取唯一可用的对象
    public static SingletonHunger getInstance(){
        return instance;
    }

    public void showMessage(){
        log.info("Hunger say Hello World!=========="+instance.hashCode());
    }
}

 

 

懒汉安全

/**
 * 懒汉安全
 */
@Slf4j
public class SingletonLazySafe {
    //创建 SingleObject 的一个对象
    private static SingletonLazySafe instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonLazySafe(){}

    //获取唯一可用的对象
    public static synchronized SingletonLazySafe getInstance(){
        if (instance ==null){
            instance=new SingletonLazySafe();
        }
        return instance;
    }

    public void showMessage(){
        log.info("Lazy Safe say Hello World!=========="+instance.hashCode());
    }
}

 

懒汉非安全

/**
 * 懒汉非安全
 */
@Slf4j
@Service("lazyUnSafe")
public class SingletonLazyUnSafe {
    //创建 SingleObject 的一个对象
    private static SingletonLazyUnSafe instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonLazyUnSafe(){}

    //获取唯一可用的对象
    public static SingletonLazyUnSafe getInstance(){
        if (instance ==null){
            instance=new SingletonLazyUnSafe();
        }
        return instance;
    }

    public void showMessage(){
        log.info("Lazy UnSafe say Hello World!=========="+instance.hashCode());
    }
}

 

静态内部类

/**
 * 静态内部类
 */
@Slf4j
@Service("staticInner")
public class SingletonStaticInner {
    private static class SingletonStaticInnerClass{
        //创建 SingleObject 的一个对象
        private static final SingletonStaticInner instance = new SingletonStaticInner();
    }

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonStaticInner(){}

    //获取唯一可用的对象
    public static SingletonStaticInner getInstance(){
        return SingletonStaticInnerClass.instance;
    }

    public void showMessage(){
        log.info("DCL say Hello World!=========="+SingletonStaticInnerClass.instance.hashCode());
    }
}

 

 

测试类

/**
 * 设计模式控制器
 */
@RestController
@RequestMapping("/designPattern")
@Slf4j
public class DesignController {
    @GetMapping("/singleton")
    public ResponseModel singleton(String singletonType) {
        if (StringUtils.isEmpty(singletonType)) {
            return new ResponseModel("请输入正确的单例模式类型", 500, null);
        }
        if (StFlag.DCL.equals(singletonType)) {
            SingletonDCL instance = SingletonDCL.getInstance();
            instance.showMessage();
            return new ResponseModel("双重检验锁单例创建成功", 200, instance.hashCode());
        } else if (StFlag.HUNDER.equals(singletonType)) {
            SingletonHunger instance = SingletonHunger.getInstance();
            instance.showMessage();
            return new ResponseModel("饿汉式单例创建成功", 200, instance.hashCode());

        } else if (StFlag.LAZYSAFE.equals(singletonType)) {
            SingletonLazySafe instance = SingletonLazySafe.getInstance();
            instance.showMessage();
            return new ResponseModel("懒汉式安全单例创建成功", 200, instance.hashCode());

        } else if (StFlag.LAZYUNSAFE.equals(singletonType)) {
            SingletonLazyUnSafe instance = SingletonLazyUnSafe.getInstance();
            instance.showMessage();
            return new ResponseModel("懒汉式非安全单例创建成功", 200, instance.hashCode());

        } else if (StFlag.STATICINNER.equals(singletonType)) {
            SingletonStaticInner instance = SingletonStaticInner.getInstance();
            instance.showMessage();
            return new ResponseModel("内部类单例成功", 200, instance.hashCode());
        }
        return null;
    }
}

 

测试案例

每个请求发两次比较hash值

饿汉式

 

 

双重检验锁

 

 

懒汉非安全

 

 

懒汉式安全

 

 

静态内部类

 

 

控制台日志

2022-06-16 02:01:18.638 INFO  Hunger say Hello World!==========593888302 【http-nio-8081-exec-4】【SingletonHunger:212022-06-16 02:01:29.767 INFO  Hunger say Hello World!==========593888302 【http-nio-8081-exec-2】【SingletonHunger:212022-06-16 02:02:13.813 INFO  DCL say Hello World!==========682619383 【http-nio-8081-exec-1】【SingletonDCL:312022-06-16 02:02:15.836 INFO  DCL say Hello World!==========682619383 【http-nio-8081-exec-9】【SingletonDCL:312022-06-16 02:02:47.905 INFO  Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-10】【SingletonLazyUnSafe:242022-06-16 02:02:50.264 INFO  Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-8】【SingletonLazyUnSafe:242022-06-16 02:03:11.053 INFO  Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-7】【SingletonLazySafe:242022-06-16 02:03:15.359 INFO  Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-6】【SingletonLazySafe:242022-06-16 02:03:37.376 INFO  DCL say Hello World!==========150313621 【http-nio-8081-exec-5】【SingletonStaticInner:262022-06-16 02:03:39.190 INFO  DCL say Hello World!==========150313621 【http-nio-8081-exec-3】【SingletonStaticInner:26】