懒汉单例模式 java_Java单例模式之懒汉模式线程安全

单例模式是设计模式中用得比较多的一种设计模式,它的主要优点有:

1.访问受控,保证访问的是唯一的实例。

2.由于只有一个实例,所以节省资源。

缺点:

灵活性低,如果对象的应用场景多变,则不适用单例模式。

如何实现单例模式?

1.1 懒汉模式(线程不安全)

想要实现单例,莫非就是要适用static关键字,如下声明一个对象:

public class SingleTon {

private static SingleTon singleTon = null;

}

这样我们就得到了一个类型为SingleTon的静态变量,接下来,我们就要控制这个类,不能被任意的new出来,这个就是实现了单例模式唯一性的根本,代码如下:

public classSingleTon {private static SingleTon singleTon = null;//把构造函数设置为private,防止被new实例化

privateSingleTon() {}public staticSingleTon getInstance() {//每次调用SingleTon.getInstance()时返回的都是singleTon唯一对象

if( singleTon == null) {

singleTon= newSingleTon();

}returnsingleTon;

}

这种模式的单例在非并发环境下是可靠的,我们知道,我们保证类是单例的代码关键是

if(singleTon == null)

并且java中new是不具有原子性的(涉及到赋值问题),所以,在并发环境下,是可能执行了多次的new操作,造成实例非唯一性。

1.2如何解决?

为了解决问题,首先就要明白问题产生的原因:

上述懒汉产生多个实例造成单例失效的原因是在高并发环境下可能同时有2个或以上的线程访问getInstance()类方法,又因为new操作不具有原子性,所以会导致产生2个实例的问题。

因此,我们可以:

1.通过添加synchronized来修饰getInstance()方法,简单有效粗暴,但是往往暴力使用同步方法带来的问题都是一样的,就是惨重的效率代价~

2.通过添加synchronized来同步部分代码块,并且通过volatile来防止指令重排,代码如下:

public classSingleTon {private static SingleTon singleTon = null;privateSingleTon() {}public staticSingleTon getInstance() {if( singleTon == null) {synchronized( SingleTon.class) {if( singleTon == null) {

singleTon= newSingleTon();

}

}

}returnsingleTon;

}

}

上述方法就是传说中的DCL双重检查锁定单例(JDK1.5之后的版本)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值