上一篇文章讲到了饿汉式有占用资源而不使用的嫌疑,那我们就应该考虑到调用的时候在生成对象。
改后的第一版本
public class LazySingletion {
private LazySingletion(){
}
private static LazySingletion single;
protected static LazySingletion getInstance(){
if(single == null ){
single = new LazySingletion();
}
return single;
}
}
这里先买个关子,大家看出了有这问题没?
1.0版本会有线程不安全的情况,在多线程下,会出现多个对象实例。
新建一个类实现Runnable接口
public class ExectorThread implements Runnable {
public void run() {
LazySingletion singleton = LazySingletion.getInstance();
System.out.println(Thread.currentThread().getName()+":"+singleton);
}
}
新建测试类
public class Test {
public static void main(String[] args) {
Thread thread1 = new Thread(new ExectorThread());
Thread thread2 = new Thread(new ExectorThread());
thread1.start();
thread2.start();
System.out.println("====");
}
}
通过多次测试,就会发现结果可能出现相同对象,也可能出现不同。
那这个时候我们就可以考虑对创建对象的函数进行加锁。
2.0版本
public class LazySingletion {
private LazySingletion(){
}
private static LazySingletion single;
protected synchronized static LazySingletion getInstance(){
if(single == null ){
single = new LazySingletion();
}
return single;
}
}
这样子就避免了线程不安全,但这也存在问题,那就是加锁后,其他线程要等待,容易造成性能下降。
那如何解决?大家先思考,下一节内容进行简答