写一下双重检测单例模式(小意思):
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. }