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

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

🍁 作者:知识浅谈,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种设计模式种的单例模式浅谈,希望有所帮助。

相关文章
|
4月前
|
设计模式 安全
详细讲解什么是单例模式
详细讲解什么是单例模式
|
1月前
|
存储 设计模式 测试技术
单例模式
单例模式
|
4月前
|
安全 C++
C++单例模式
C++单例模式
47 1
|
设计模式 Java Spring
什么场景要使用单例模式,什么场景不能使用?
经常有小伙伴问我,设计模式学了这么久,每次看到概念也都能理解。但是,就是不知道怎么用,在哪里能用?我告诉大家,设计模式,不是为了要用而用的,而是作为前人总结下来的经验,等到哪天需要用的时候,你能想起来为你所用。
92 0
|
安全 Java
原来要这么实现单例模式
原来要这么实现单例模式
50 0
找对象需要单例模式吗?
单例模式的类只提供私有的构造函数
|
SQL 安全 Java
五种单例模式介绍
五种单例模式介绍
86 0
|
存储 安全 调度
单例模式的简单介绍
单例模式的简单介绍
|
设计模式 安全 前端开发
关于单例模式,你应该了解这些
关于单例模式,你应该了解这些
关于单例模式,你应该了解这些
|
设计模式 缓存
我学会了,单例模式
单例模式属于创建型模式,这个类型的设计模式是将 对象的创建和使用解耦了,花式的去创建对象。
121 0
我学会了,单例模式