首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java创建线程安全的单例singleton

Java创建线程安全的单例

单例的使用场景

、JVM中仅需要一个实例,因此能节省内存,加快访问速度,比如数据库连接池,计数器等。

、Spring 中的Bean,默认也是单例的,

、共享资源的访问,比如日志文件,系统配置

单例的实现

要实现一个单例,首先要把构造方法设置成私有的,并且要提供一个返回实例的方法

1、实现一个单例,单线程是安全的,多线程中不安全,代码如下:

实现一个单例,单线程是安全的

如果多线程下,如果第一个线程执行检查instance是否为null,如果为null,执行创建一个Singleton1的实例,在实例未被初始化完毕的时候,第二个线程检查instance是否为null,这时候是null,也会创建一个实例。这时候就会有两个实例。

2、多线程下的安全单例,第一种方式就是方法加锁来实现,比如添加关键字synchronized。

多线程下的安全单例

添加了一个synchronized关键字,实现了多线程下的安全单例,每次获取会锁住Class对象,导致性能不高。

3、多线程下的安全单例,第二种方式就是双重检查,下面的实现方式有问题吗?

实现双重检查

不在方法上添加synchronized,在instance为null的时候才会添加锁,这样效率提高了不少,但是在多线程下面可能会出现问题。原因是创建实例的时候,有几个步骤(分配空间,初始化,把instance执行分配的地址),这几个步骤会被处理器重排序,导致在没有完全初始化的情况下其他线程获取了实例,可能会导致莫名其妙的问题。

4、第三种方式实现多线程下的安全单例,在上个例子中,把instance设置为volatile,这个关键字能保可见性,其实是阻止了重排序(分配空间,初始化,把instance执行分配的地址)。

第三种方式实现多线程下的安全单例

5、第四种方式实现多线程下的安全单例,使用饿汉式,缺点就是不能延迟加载。

饿汉式多线程下的安全单例

6、第五种方式实现多线程下的安全单例,基于类的初始化,在类初始化的时候,JVM会获取一个锁,这个锁可以同步多个线程对同一个类的初始化。

基于类的初始化的单例

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200313A0U7U100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券