面试官:写一下双重检测单例模式,解释一下每一行,volatile的作用,不加会有什么问题,去掉第一层循环有什么问题,去掉第二呢

举报
知识浅谈 发表于 2022/08/17 09:18:23 2022/08/17
【摘要】 面试官:写一下双重检测单例模式,解释一下每一行,volatile的作用,不加会有什么问题,去掉第一层循环会有什么问题,去掉第二层循环会有什么问题。

写一下双重检测单例模式(小意思):

1. public class Test {
2. private static volatile Test test;
3. private Test(){}
4. public Test getSingleTan(){
5. if (test==null){
6. synchronized (Test.class){
7. if(test==null){
8.                     test = new Test();
9.                 }
10. return test;
11.             }
12.         }
13. return test;
14.     }
15. }

解释一下每一行

private static volatile Test test;   //创建一个静态可见性的对象

private Test(){}                    //构造函数私有话,不让外部创建对象

public Test getSingleTan(){

   if (test==null){                //检查test是否被初始化

       synchronized (Test.class){    //对Test.class 加锁进行初始化 ,当然这个可能会有多个线程走到这再次获得锁

           if(test==null){          //防止上边多个线程获得锁之后多次初始化,

               test = new Test();  //创建单例对象

           }

           return test;

       }

   }

   return test;                 //创建之后返回

}

volatile的作用

因为volatile修饰的变量具有可见性和有序性,我们创建单例模式是在多个线程返回的同一个单例对象,这个volatile修饰,就是当创建成功之后其他西安城也能及时看到就不再创建单例对象。

 

不加会有什么问题

不加就会创建单例对象被覆盖,如果之前创建好兵器赋了相应的值,就会被覆盖掉。

 

去掉第一层循环会有什么问题

之所以第一层在,就是为了当已经创建过单例对象就不用再去获取锁,减少了去尝试获取锁的过程减少了时间的消耗,所以如果去掉这个就会比不去掉耗时较多。

 

去掉第二层循环会有什么问题

第二层循环就是为了防止多个线程同时进入第一层循环,如果进入第一层循环的有三个线程,第一个线程获取锁创建对象之后其他两个获取锁之后也不能在创建对象了,如果把第二层去掉之后就会创建3个对象,也就破坏了单例模式的概念。

 

 

兴致比较高再写一个静态内部类的单例模式

为什么静态内部类能做单例模式? 因为静态内部类只会加载一次

1. class Test{    
2. public Test getSingleTan() {
3. return T.test1;
4.     }
5. 
6. static class T{
7. private static volatile Test test1=new Test();
8.     }
9. }
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。