大佬,人人都说精通的单例模式,你精通了吗

简介: 大佬,人人都说精通的单例模式,你精通了吗

🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主

📌 擅长领域:全栈工程师、爬虫、ACM算法

💒 公众号:知识浅谈

🔥 联系方式vx:zsqtcc

🤞大佬,人人都说精通的单例模式,你精通了吗🤞

正菜来了⛳⛳⛳

概括起来,要实现一个单例,需要关注的点有下面几个:

  • 构造函数需要是private访问权限的,这样才能避免外部通过new创建实例;
  • 考虑对象创建时的线程安全问题;
  • 考虑是否支持延迟加载:
  • 考虑getlnstance0性能是否高(是否加锁)

🎈饿汉式

类加载时直接实例化单例对象

饿汉式的实现方式比较简单。在类加载的时候,instance静态实例就已经创建并初始化好了,所以,instance实例的创建过程是线程安全的。不过,这样的实现方式不支持延迟加载(在真正用到IdGenerator的时候,再创建实例),从名字中我们也可以看出这一点。

具体的代码实现如下所示:

public class Main { 
    //在类加载的时候就已经实例化好了,不好的地方就是如果用不到就相当于无效占用空间了,但是不会出现多线程的问题
    private static Main test = new Main();
    private Main(){}
    public Main getInstance(){
      return test;
    }
    public static void main(String[] args) {
        System.out.println(Main.test);
    }
}

🎈懒汉式

🍮双重检查模式

之所以双重检查,为了保证多线程创建多个对象形成覆盖的问题。

为什么使用volatile,是因为只有加了volatile,才能保证可见性,在不同的线程中对象的变量值都是可见的。

public class Main {
    private static volatile Main test;
    private Main(){}
    public static Main getInstance(){
        if(test==null){
            synchronized (Main.class){
                if(test==null) test = new Main();
            }
        }
        return test;
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        CountDownLatch count = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Main.getInstance());
                    count.countDown();
                }
            });
        }
        count.await();
        executorService.shutdown();
    }
}

🍮静态内部类模式

主要用到的原理是 首先静态内部类只有在调用的时候,第一次进行初始化,也就是单例对象只在第一次调用的时候创建

public class Main {
    private Main(){}
    static class A{
        private static Main test = new Main();
    }
    public static Main getInstance(){
        return A.test;
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        CountDownLatch count = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Main.getInstance());
                    count.countDown();
                }
            });
        }
        count.await();
        executorService.shutdown();
    }
}

🍚总结

以上就是个人对23种设计模式种的单例模式浅谈,希望有所帮助。

相关文章
|
6月前
|
设计模式 安全 测试技术
【C++】—— 单例模式详解
【C++】—— 单例模式详解
|
6月前
|
设计模式 安全
详细讲解什么是单例模式
详细讲解什么是单例模式
|
5月前
|
设计模式 安全 Java
单例模式分享
单例模式分享
23 0
|
6月前
|
C++
【C++ 单例模式】
【C++ 单例模式】
|
设计模式 前端开发
关于单例模式我所知道的
关于单例模式我所知道的
58 0
关于单例模式我所知道的
|
设计模式 缓存 JSON
没那么简单的单例模式
没那么简单的单例模式
126 0
没那么简单的单例模式
|
SQL 安全 Java
单例模式的理解
谈谈你对单例模式的理解。也算是老生常谈的问题了~~~
1037 1
|
SQL 设计模式 安全
单例模式详解
单例模式详解
241 0
单例模式详解
|
开发框架 安全 Java
单例模式的应用(1)
单例模式的应用(1)
144 0
|
存储 设计模式 缓存
浅谈单例模式
本文描述设计模式中的单例模式