美文网首页
单例模式有哪些写法

单例模式有哪些写法

作者: 张某某xyz | 来源:发表于2021-08-28 12:28 被阅读0次

20210828

饿汉模式、懒汉模式

建议使用饿汉,因为简单

饿汉模式

类加载时就创建实例,缺点是假如这个单例类一直不被用到,创建出来的对象就是个浪费

class SingleHungry {
    private static final SingleHungry singleHungry = new SingleHungry();

    private SingleHungry() {
    }

    public static SingleHungry getInstance() {
        return singleHungry;
    }
}

测试代码:

public class SingleHungryTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                String hashcode = SingleHungry.getInstance().hashCode() + "";
                if (list.isEmpty()) list.add(hashcode);
                if (!list.contains(hashcode)) System.out.println("非单例");
            }).start();
        }
    }
}

懒汉模式

当第一次用到时才创建实例

class SingleLazy {
    // volatile是防止singleLazy = new SingleLazy()时指令重排
    private volatile static SingleLazy singleLazy;

    private SingleLazy() {
        MyThreadUtil.sleepSeconds(5);//模拟创建对象时的延时
    }

    /**
     * 2次if判,所以叫DCL:double check lazy
     */
    public static SingleLazy getInstance() {
        if (singleLazy == null) {
            synchronized (SingleLazy.class) {
                if (singleLazy == null) singleLazy = new SingleLazy();
            }
        }
        return singleLazy;
    }
}

测试代码:

public class SingleLazyTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                String hashcode = SingleLazy.getInstance().hashCode() + "";
                if (list.isEmpty()) list.add(hashcode);
                if (!list.contains(hashcode)) System.out.println("非单例");
            }).start();
        }
    }
}

为什么要写2次if(DCL)

直接锁整个方法,正确,但是效率低

   public synchronized static SingleLazy getInstance() {
        if (singleLazy == null) singleLazy = new SingleLazy();
        return singleLazy;
    }

等同于:

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

上面2种写法的问题在于,当实例已经创建后,并发的线程还是会阻塞,于是改进成:

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

为什么要用volatile修饰实例

private volatile static SingleLazy singleLazy;

创建实例的代码singleLazy = new SingleLazy()对于的字节码指令是3个:

1.创建实例,分配内存
2.初始化实例
3.将singleLazy指向分配的内存

指令重排可能导致字节码的执行顺序是132,当一个线程发现singleLazy!=null,就直接返回他,但是实例还没有初始化完成,这样在使用实例时报错(指令重排成132的概率很小很小很小)

相关文章

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • 单例模式有哪些写法

    20210828 饿汉模式、懒汉模式 建议使用饿汉,因为简单 饿汉模式 类加载时就创建实例,缺点是假如这个单例类一...

  • Kotlin中的单例模式与Java对比

    目前java中的单例模式有多种写法,kotlin中的写法更多一点,本篇会总结全部的到单例模式写法。 一、懒人写法(...

  • 第03条 用私有构造方法或者枚举类型强化Singleton属性

    单例模式最佳写法1 - 双重校验锁 单例模式最佳写法2 - 静态内部类

  • 单例模式

    单例模式--概念 单例模式常见的写法有:懒汉式,饿汉式,登记式。单例模式的特点有:1.单例类只能有1个实例2.单例...

  • Java设计模式—单例模式

    概念 java中单例模式是一种常见的设计模式,单例模式的写法有好几种,比较常见的有:懒汉式单例、饿汉式单例。单例模...

  • Android开发教程——设计模式之单例模式

    这篇文章将解决你以下几个疑问: 为什么要使用单例? 单例有哪些写法? 单例存在哪些问题? 单例与静态类的区别? 有...

  • java 24 设计模式

    单例模式java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、...

  • 单例的2种写法

    单例模式是iOS开发中最常用的设计模式,iOS的单例模式有两种官方写法,如下: 1,常用写法 import "Se...

  • Java设计模式_单例模式

    概念 java中单例模式是一种常见的设计模式,单例模式的写法有好几种.这里主要介绍:懒汉式 饿汉式. 单例模式有...

网友评论

      本文标题:单例模式有哪些写法

      本文链接:https://www.haomeiwen.com/subject/svdcbltx.html