单例模式如何实现线程安全
2018-04-04 00:00
363 查看
摘要: 线程安全下的单例模式
单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。那我们如何在多线程下保证单例模式的线程安全呢?博主总结有以下几种方法:
1.饿汉式的单例模式
单例类如下,饿汉式就是在调用getSingle()方法前,就已经创建了一个Single对象。如下图:
线程类如下:
执行结果如下:
从运行结果我们可以看出,在5个线程都去调用单例对象时,输出的hash值是同一个,证明我们保证了线程安全。
2.饱汉式的单例模式
单例类如下,饱汉式就是在调用getSingle()方法时才创建一个Single对象。如下图:
这样的写法会导致一个问题,当两个线程同时访问这个单例类时,两个线程同时走到判断single==null这里时,都判断是没有的,就会出现问题,他们都会重新创建一个新的single对象。导致出现以下结果:
出现了不一样的hash值,所以上面的写法是无法实现线程安全的,那么怎么改进呢?
(1)在方法加上synchronized关键字
我们可以在获取单例对象的方法加上synchronized关键字。如下:
(2)静态代码块加锁
也可以采用静态代码块加锁会出现问题的地方,由于同一个对象中的所有同步方法同一时间只能有其中一个可以在一个线程中执行,加入synchronized关键字后,同步会影响程序运行效率,所以synchronized包裹的代码越少越好。如下图:
(3)采用双重锁机制
未完,待续。。。
单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。那我们如何在多线程下保证单例模式的线程安全呢?博主总结有以下几种方法:
1.饿汉式的单例模式
单例类如下,饿汉式就是在调用getSingle()方法前,就已经创建了一个Single对象。如下图:
线程类如下:
执行结果如下:
从运行结果我们可以看出,在5个线程都去调用单例对象时,输出的hash值是同一个,证明我们保证了线程安全。
2.饱汉式的单例模式
单例类如下,饱汉式就是在调用getSingle()方法时才创建一个Single对象。如下图:
这样的写法会导致一个问题,当两个线程同时访问这个单例类时,两个线程同时走到判断single==null这里时,都判断是没有的,就会出现问题,他们都会重新创建一个新的single对象。导致出现以下结果:
出现了不一样的hash值,所以上面的写法是无法实现线程安全的,那么怎么改进呢?
(1)在方法加上synchronized关键字
我们可以在获取单例对象的方法加上synchronized关键字。如下:
(2)静态代码块加锁
也可以采用静态代码块加锁会出现问题的地方,由于同一个对象中的所有同步方法同一时间只能有其中一个可以在一个线程中执行,加入synchronized关键字后,同步会影响程序运行效率,所以synchronized包裹的代码越少越好。如下图:
(3)采用双重锁机制
未完,待续。。。
相关文章推荐
- 用C++实现单例模式3——如何在不使用锁和C++11的情况下,用C++实现线程安全的Singleton
- 关于单例模式这种比上面1、2都好一些,既实现了线程安全,又避免了同步带来的性能影响。
- 如何开发一个java开源框架-----Jvn框架之实现mvc框架模式(第一讲)
- ArrayList如何实现线程安全
- 如何使用 Java8 实现观察者模式
- 牛客网Java刷题知识点之为什么HashMap不支持线程的同步,不是线程安全的?如何实现HashMap的同步?
- 如何使用 Java8 实现观察者模式?(上)
- 如何实现servlet的单线程模式
- 一起学习水晶报表之拉模式【如何实现水晶报表显示数据信息】(课程3)
- 关于基于Event Sourcing模式实现的领域模型如何处理模型重构的问题的思考
- 设计模式-观察者模式,以及如何使用观察者来为app实现即时通讯功能
- 如何让你的传输更安全——NIO模式和BIO模式实现SSL协议通信
- golang 如何实现线程安全的发送 ping 包
- 驰骋工作流引擎如何实现发送阻塞模式?
- 设计模式:如何使用观测者模式实现监控和推送
- 实现一个单例模式的类,要求线程安全
- 单例模式的实现,及线程安全问题
- 单例模式——C++实现线程安全的单例
- 线程安全的单例模式的几种实现方法分享
- Java中如何实现单例模式