【设计模式】——你真的会单例吗?

简介: 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)

【简介】


单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)


20200229221932657.png


【场景】


现实中有意思的场景可以查阅小编之前总结的一篇博客:找对象需要单例模式吗?


适用单例的条件:


一、某个类只能有一个实例


二、是它必须自行创建这个实例


三、是它必须自行向整个系统提供这个实例。


单例具体实现要求:


一、是单例模式的类只提供私有的构造函数


二、是类定义中含有一个该类的静态私有对象


三、是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。


【示例】


一、饿汉式,私有静态变量初始化方式(简单易用,能满足大部分要求)


说明:类加载到内存后,就实例化一个单例,jvm保证线程安全(缺点:不管用到与否,类装载时就会完成实例化)


public class Mar1 {
    private static Mar1 INSTANCE = new Mar1();
    private Mar1(){}
    public static Mar1 getInstance(){
        return INSTANCE;
    }
    public static void main(String[] args) {
        Mar1 mar1 = Mar1.getInstance();
        Mar1 mar11 = Mar1.getInstance();
        System.out.println(mar1 == mar11);
    }
}


二、懒汉式,锁方法


说明:需要用到的时候再进行实例创建(缺点:并发带来效率低下的问题)


注:volatile关键字可以规避指令重排带来的不安全性(idea中可以查看编辑指令)


public class Mar4 {
    private static volatile Mar4 INSTANCE;
    private Mar4(){}
    public static synchronized Mar4 getInstance(){
        if(INSTANCE == null){
            //测试并发加入的睡眠
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mar4();
        }
        return INSTANCE;
    }
    public static void main(String[] args) {
        for (int i = 0; i<100;i++){
            new Thread(()->{
                System.out.println(Mar4.getInstance().hashCode());
            }).start();
        }
    }
}


三、懒汉式,局部锁,双重判定


说明:需要用到的时候再进行实例创建,相对于二的效率得到了一些提升


public class Mar6 {
    private static volatile Mar6 INSTANCE;
    private Mar6(){}
    public static Mar6 getInstance(){
        if(INSTANCE == null){
            synchronized(Mar6.class){
                if(INSTANCE == null) {
                    //测试并发加入的睡眠
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Mar6();
                }
            }
        }
        return INSTANCE;
    }
    public static void main(String[] args) {
        for (int i = 0; i<100;i++){
            new Thread(()->{
                System.out.println(Mar6.getInstance().hashCode());
            }).start();
        }
    }
}


四、懒汉式,内部类实现


说明:类加载的时候不会去加载内部类,当使用到调用的时候才会进行实例化


public class Mar7 {
    private Mar7(){}
    private static class Mar7Holder{
        private static Mar7 INSTANCE = new Mar7();
    }
    public static Mar7 getInstance(){
        return Mar7Holder.INSTANCE;
    }
    public static void main(String[] args) {
        for (int i = 0; i<100;i++){
            new Thread(()->{
                System.out.println(Mar7.getInstance().hashCode());
            }).start();
        }
    }
}


五、枚举方式(effectice java书中提到的)


说明:不仅可以解决线程安全还可以防止反序列化


public  enum  Mar8 {
    INSTANCE;
    public static void main(String[] args) {
        for (int i = 0; i<100;i++){
            new Thread(()->{
                System.out.println(Mar8.INSTANCE.hashCode());
            }).start();
        }
    }
}


【总结】


通过学习各种形式的单例模式,对单例又有了一个更加深刻的认识。


1.利用java中的特性来解决(内部类、枚举类)


2.使用锁的时候要在保证安全的前提控制锁的粒度


3.通过学习单例对以后code更有干劲


4.激发了自己了解其它模式更加浓厚的兴趣与爱好

相关文章
|
6月前
|
设计模式
单例设计模式步骤
单例设计模式步骤
35 1
|
6月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
145 0
|
6月前
|
设计模式 安全 Java
最简单的设计模式是单例?
单例模式可以说是Java中最简单的设计模式,但同时也是技术面试中频率极高的面试题。因为它不仅涉及到设计模式,还包括了关于线程安全、内存模型、类加载等机制。所以说它是最简单的吗?
80 3
最简单的设计模式是单例?
|
6月前
|
设计模式 安全 Java
【设计模式】2、设计模式分类和单例设计模式
【设计模式】2、设计模式分类和单例设计模式
58 0
|
6月前
|
设计模式 消息中间件 安全
多线程编程设计模式(单例,阻塞队列,定时器,线程池)(二)
多线程编程设计模式(单例,阻塞队列,定时器,线程池)(二)
60 1
|
6月前
|
设计模式 Java
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
56 2
|
6月前
|
设计模式 安全 Java
在Java中即指单例设计模式
在Java中即指单例设计模式
40 0
|
2月前
|
设计模式 存储 安全
设计模式——设计模式介绍和单例设计模式
饿汉式(静态常量)、饿汉式(静态代码块)、懒汉式(线程不安全)、懒汉式(线程安全,同步方法)、懒汉式(线程不安全,同步代码块)、双重检查(推荐,线程安全、懒加载)、静态内部类(推荐)、枚举(推荐)
设计模式——设计模式介绍和单例设计模式
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
56 1
|
6月前
|
设计模式 安全 Java
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式