懒汉式是不安全的,这是因为如果有两个线程同时进入到Single2类中的getInstance()方法就会返回该类的两个实例对象,这就违背了单例模式的设计初衷。
那么第二种有安全隐患的方法有没有改进方法呢,当然看如下代码:
class Single3
{
private static Single s = null;
private Single3(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single3.class)
{
if(s==null)
s = new Single3();
}
}
return s;
}
}
将创建对象的代码块加上锁,并且这个是一个静态方法,拥有这个锁的对象是这个类本身,即Single.class(代表该类的字节码)。并且这个getInstance方法为什么进行两次“s==null”判断呢?是因为提高效率,因为在执行到第一个“s==null”的判断语句时,不满足条件的将不会进入if语句体内,只有极少数同时执行了这个判断语句的线程才会进入,再对这一小部分进行锁的判断(判断锁很耗费资源,因为我写了个while(true)循环试了下,cpu很快就达到%90了。。),这便提高了效率。 |