class Consumer {
private static Consumer consumer;
private Consumer(){}
public static Consumer getInstance(){
if (consumer==null) {
synchronized (Consumer.class) {
consumer=new Consumer();
}
}
return consumer;
}
@Override
public String toString() {
return super.toString();
}
}
public class ConsumerTest {
public static void main(String[] args) {
System.out.println(Consumer.getInstance());
System.out.println(Consumer.getInstance());
System.out.println(Consumer.getInstance());
}
}
你这个写法是线程不安全的,是有问题的,
当你的getInstance在不同线程中分别调用时,假如线程1走到了consumer=new Consumer();这行代码,这个时候Cpu将运行机会分配了线程2,
线程2 走到 synchronized (Consumer.class) { 这行代码,发现代码锁住了,因为线程1正在里面,于是乎wait住了,于是线程1继续执行,
创建了一个 consumer 对象,这个时候线程1已经完全执行完成,线程2也发现 synchronized 已经 没有锁住了,于是接着执行,这样的话 就又创建了一个consumer对象,所以正确的写法应该是如下:
public class Single_lhs {
private static Single_lhs s=null;
private Single_lhs()
{
}
public static Single_lhs getInstance()
{
if (s==null) {
synchronized (Single_lhs.class) {
if (s==null) {
s=new Single_lhs();
}
}
}
return s;
}
}
在同步锁后面在使用一个null判断,保证线程2起来后,发现对象已经不为null,因此避免了重复创建。