单例模式 (懒汉式, 线程同步详解)
来源:互联网 发布:樱井翔堀北真希 知乎 编辑:程序博客网 时间:2024/05/18 00:57
单例模式(懒汉式)
在懒汉式写法中, 我们需要非常注意线程同步的问题. 大概有一下几个:
1. getInstance() 直接锁方法好不好
2. 双重锁定
3. synchronized(this)行不行
1. getInstance() 直接锁方法好不好
这种写法:
class Singleton { private static Singleton instance; private Singleton(){} public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; }}
我们可以看到这里synchronized是锁方法, 当两个线程都要进入getInstance()时, 只有一个能进入, 并创建出实例, 然后另外一个进入后, 判断 instace不为null, 然后直接得到instance. 这种做法是没有错误的. 但是由于线程都需要通过getInstance()来获取对象, 所以getInstance()调用频率很高, 所以线程被锁的频率也很高, 所以这种做法效率低.
2. 双重锁定
由于上面效率的原因, 你可能就会想到把 syschronized 放在 getInstance()里面, 这种可避免在调用getInstance()时的阻塞问题, 如下:
class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized(Singleton.class){ instance = new Singleton(); } } return instance; }}
这种写法看似没有问题, 其实却有一个很大的隐患, 在于: 如果两个线程同时执行getInstance(),判断 instance都不为null后, 进入if判断语句. 这个时候一个线程获得锁, 然后进入new了一个对象, 并开心的执行完了. 这个时候另外一个线程获得了锁, 但让它也不会再去判断 instace是否为null, 所以它也会再执行一次new操作. 所以这里执行了两次new操作. 当然最后instance还是只指向后一次new的对象.
所以这个时候需要双重锁定, 就是在 synchronized中再加一次 null判断, 如下:
class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized(Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; }}
这样就可以保证不会new两次, 也是相对比较正确的, 并且效率也很高.
3. synchronized(this)行不行
答案是不行的, 如果你写代码看一看, 直接就提示语法错误了, 因为我们的 getInstance() 方法是 static的, 所以里面不能使用 this.
好了以上三点终结, 希望对大家有帮助.
- 单例模式 (懒汉式, 线程同步详解)
- 单例模式(懒汉模式)中的线程同步问题
- 解决单例设计模式中懒汉式线程安全问题
- 解决单例设计模式中懒汉式线程安全问题
- 单例模式---懒汉式
- 单例模式-懒汉式
- 单例模式--饿汉式、懒汉式、线程安全的懒汉式、高性能安全的懒汉式
- 饿汉式和懒汉式(单例模式详解)
- 懒汉单例模式
- 单例模式之懒汉模式的线程安全解决方法
- Java单例模式——互斥锁-单例之懒汉式的线程安全
- (2.2.2.3)设计模式--单例模式(三)改进型懒汉式-线程安全型
- 单例模式(2.懒汉式)
- 单例模式 饿汉式 懒汉式
- 【单例模式】饿汉式&懒汉式
- 单例模式(懒汉、恶汉式)
- 单例设计模式II (懒汉式)
- 懒汉式 && 饿汉式 的单例模式
- Caffe下学习速率调整策略摘抄
- java项目开发过程中自己挖过的坑
- netbeans 快捷键
- svn clean up 时 .svn\pristine\cc\cca2e58e9e310a113a37e3bd87eae3a42434e899.svn-base 找不到文件解决方法
- bzoj 4521: [Cqoi2016]手机号码
- 单例模式 (懒汉式, 线程同步详解)
- UITableView的使用
- Unity 使用C#翻转图片并缩放
- Jsp标签
- ulimit 命令详解
- 为Jpanel设置背景图片
- pureMVC框架 子类实现父类的接口的目的
- 桥接模式
- Preference Learning——Object Ranking:Learning to Order Things