您的位置:首页 > 其它

线程安全的"懒汉"单例模式

2018-02-27 17:00 465 查看
所谓线程不安全实际上就是一段代码在同一时间被两个线程同时执行,导致运行结果与单个线程运行结果不相同

新建一个单例模式类和一个多线程测试类

public class TestSingleTon implements Runnable{

public static void main(String[] args) {
TestSingleTon t1 = new TestSingleTon();
TestSingleTon t2 = new TestSingleTon();

Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);
thread1.start();
thread2.start();
}

@Override
public void run() {
System.out.println(SingleTon.getInstance());

}

}

public class SingleTon {
private static SingleTon singleTon;

public static SingleTon getInstance() {
    if(singleTon==null) {
singleTon = new SingleTon();
}
return singleTon;
}

}


执行后发现控制台打印了两个不同的对象:

com.wey.demo.SingleTon@22896964
com.wey.demo.SingleTon@1ac5e970


说明有线程并发访问安全问题,获取的不是同一个实例

解决方案(1):使用同步锁机制,最简单的是在getInstance()方法上加synchronized关键字

public synchronized static SingleTon getInstance() {
if(singleTon==null) {
singleTon = new SingleTon();
}
return singleTon;
}


对于这种方式,有人觉得在多并发的情况下,每次获取实例都要判断锁,效率比较低下,所以就有人想出了这样的办法,双重判断实例,这种大大减少判断同步锁的次数了。所以实际使用中可以推广。

public static SingleTon getInstance() {
if(singleTon==null) {
synchronized (SingleTon.class) {//SingleTon的字节码
if(singleTon==null) {
singleTon = new SingleTon();
}
}
}
return singleTon;
}


解决方案(2):改懒汉式单例为饿汉式单例

public class SingleTon {
private static SingleTon singleTon = new SingleTon();

public static SingleTon getInstance() {
return singleTon;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: