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