java单例模式线程安全_Java单例模式以及线程安全性的保证

1.单例模式有什么用处?

有一些对象只能使用一个,例如:数据库连接、线程池(threadpool)、缓存(cache)、对话框、处理偏好(preferences)设置和这侧表(registry)的对象、日志对象、充当打印机、显卡等设备的驱动程序的对象,即用于管理共享的资源。这种对象只能有一个实例,制造多个会导致问题。

2.最经典的单例模式?/**

* 1.利用一个私有静态变量来记录Singleton类的唯一实例;

* 2.构造器声明为私有,只有Singleton类本身内部才可调用;

* 3.声明共有静态的方法getInstance()来实例化对象,并返回这个对象的实例;

* 4.说明:如果我们不需要这个实例,就不会调用getInstance()方法,那么这个实例就不会产生,

*        称为“延迟实例化(lazy instantiaze)”。这种做法对资源敏感的对象特别重要。

*/

public class Singleton {

private static Singleton sInstance;

private Singleton(){}

public static Singleton getInstance(){

if(sInstance == null){

sInstance = new Singleton();

}

return sInstance;

}

}

3.单例模式定义--确保一个类只有一个实例,并提供一个全局访问点。

(1)全局访问点即向外提供的获取唯一实例的唯一入口,是共有静态的,访问它对比访问一般的全局变量的优点在于:单例中的全局访问点可以做到“延迟实例化”。

(2)此时的单例可能遇到的麻烦--多线程

正如下图中情况所示,当有多个线程同时访问该访问点时,以两个线程为例,就会出现可能实例化两个对象,这对于使用单例的地方可能引发灾难呀...

8ecd98d549db768480dbb11bac9eb1e4.png

4.怎样改善多线程情况下的单例?

(1)不推荐的方法--synchronized

同步getInstance()方法既简单又有效,但是可能造成程序执行效率下降100倍,如果getInstance()被调用的频繁,只能重新考虑其他方法了;

(2)什么都不做

没错,什么都不做。如果应用程序可以接受getInstance()造成的额外负担,那就完全可以忘记这件事;

(3)使用“急切实例化(eagerly)”而非“延迟实例化”的做法

a.如果应用程序总是需要创建使用单例实例;

b.如果应用程序在创建运行时方面的负担不太重;

此时可选择“急切实例化”:public class EagerlySingleton {

/**在静态初始化器中创建单例实例,保证了线程安全**/

private static EagerlySingleton eSingletonInstance = new EagerlySingleton();

private EagerlySingleton(){};

public static EagerlySingleton getInstance(){

return eSingletonInstance;

}

}

这个做法,依赖JVM在加载这个类时就创建这个唯一的单例实例,保证了任何线程在访问这个静态变量之前,该实例已经创建。

(4)用“双重检查加锁(double checked locking)”,在getInstance()中减少使用同步/**

* 1.volatile确保实例化时,多个线程能正确的处理sInstance;

* 2.判断sInstance == null后在使用synchronized,且synchronized后在判断一次sInstance == null

* 3.双重检查加锁不适用于1.4以及更早的版本的Java。

*/

public class DoubleCheckSingleton {

private volatile static DoubleCheckSingleton sInstance;

private DoubleCheckSingleton(){}

public static DoubleCheckSingleton getInstance(){

if(sInstance == null){

synchronized (DoubleCheckSingleton.class) {

if(sInstance == null){

sInstance = new DoubleCheckSingleton();

}

}

}

return sInstance;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值