美文网首页
Java并发 | 单例的立即加载和延迟加载实现

Java并发 | 单例的立即加载和延迟加载实现

作者: icebreakeros | 来源:发表于2019-08-08 23:10 被阅读0次

单例模式

立即加载/饿汉模式

/**
 * 立即加载
 */
class MyObject {

    private static MyObject object = new MyObject();

    private MyObject() {
    }

    public static MyObject getInstance() {
        return object;
    }
}

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println(MyObject.getInstance().hashCode());
    }
}

public class Run {

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new MyThread());
            thread.start();
        }
    }
}

延迟加载/懒汉模式

第一版

存在不支持多线程问题

class MyObject {

    private volatile static MyObject object;

    private MyObject() {
    }

    public static MyObject getInstance() {
        try {
            if (Optional.ofNullable(object).isEmpty()) {
                // 模拟创建对象之前准备工作
                Thread.sleep(3000);
                object = new MyObject();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

第二版

方法加关键字synchronized,存在效率低问题

class MyObject {

    private volatile static MyObject object;

    private MyObject() {
    }

    synchronized public static MyObject getInstance() {
        try {
            if (Optional.ofNullable(object).isEmpty()) {
                // 模拟创建对象之前准备工作
                Thread.sleep(3000);
                object = new MyObject();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

第三版

针对某些重要的部分单独同步,存在不支持多线程问题

class MyObject {

    private volatile static MyObject object;

    private MyObject() {
    }

    public static MyObject getInstance() {
        try {
            if (Optional.ofNullable(object).isEmpty()) {
                // 模拟创建对象之前准备工作
                Thread.sleep(3000);
                synchronized (MyObject.class) {
                    object = new MyObject();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

最终版

使用DCL双检测锁机制

/**
 * 延迟加载
 */
class MyObject {

    private volatile static MyObject object;

    private MyObject() {
    }

    // 双检测机制
    public static MyObject getInstance() {
        try {
            if (Optional.ofNullable(object).isEmpty()) {
                // 模拟创建对象之前准备工作
                Thread.sleep(3000);
                synchronized (MyObject.class) {
                    if (Optional.ofNullable(object).isEmpty()) {
                        object = new MyObject();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println(MyObject.getInstance().hashCode());
    }
}

public class Run {

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new MyThread());
            thread.start();
        }
    }
}

相关文章

  • Java并发 | 单例的立即加载和延迟加载实现

    单例模式 立即加载/饿汉模式 延迟加载/懒汉模式 第一版 存在不支持多线程问题 第二版 方法加关键字synchro...

  • 多线程:6单例模式和多线程

    单例模式和多线程 1.立即加载 2.延迟加载 2.1 延迟加载不同步在多线程环境下的问题 2.2延迟加载的解决方案...

  • 设计模式(创建型--单例模式)

    1.饿汉式单例(立即加载方式) 2.懒汉式单例(延迟加载方式) 多线程环境下使用syhchronized 利用双重...

  • 单例模式的实现方式

    单例模式的实现 单例模式的实现一般来说有2种方式:懒汉式(延迟加载)、饿汉式(非延迟加载)。 1. 饿汉式(非延迟...

  • Java线程安全的单例模式

    简单的单例模式(饿汉模式) 程序代码加载时,单例即初始化,加重系统负载.未实现懒加载 懒加载的单例模式 双锁延迟加...

  • 设计模式系列-单例模式的N种实现与总结

    通常Java实现单例模式有很多种方式,大致可分为懒汉模式和饿汉模式,其主要区别是实例延迟加载的问题,当然单例模式往...

  • Java实际项目使用的Singleton是什么样的

    java面试经常问的一个问题就是单例怎么实现,这个问题主要考察的就是延迟加载和java的内存机制,按照通常的标准答...

  • 单例模式

    在《并发编程实战》中建议用下面这个方法:延迟初始化占位类模式实现单例模式。可以实现懒加载,也比双重检查加锁更好理解...

  • Java面试 - 单例 - 灵魂八问

    目录 1.为什么要使用单例? 2.单例有几种实现方式?<1> 饿汉模式:比较饥饿,立即加载,即类加载时就已经产生了...

  • 技术文章收集

    单例模式Java 类加载静态类加载时机

网友评论

      本文标题:Java并发 | 单例的立即加载和延迟加载实现

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