🍁 作者:知识浅谈,CSDN 签约讲师,CSDN 博客专家,华为云云享专家,阿里云专家博主
📌 擅长领域:全栈工程师、爬虫、ACM 算法
💒 公众号:知识浅谈
🔥 联系方式 vx:zsqtcc
🤞大佬,人人都说精通的单例模式,你精通了吗🤞
正菜来了⛳⛳⛳概括起来,要实现一个单例,需要关注的点有下面几个:
🎈饿汉式
类加载时直接实例化单例对象饿汉式的实现方式比较简单。在类加载的时候,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 种设计模式种的单例模式浅谈,希望有所帮助。
评论