最近在公司写需求时遇到了多线程与单例一同出现的情况。

这个时候想到的就是线程安全以及单例的定义了,虽然单例指的是在内存中它只有一份,但是并不是说就是线程安全的。

所以,我当时就到网上找了关于多线程下单例的线程安全问题的资料,然后就知道如下博客:高并发下线程安全的单例模式(最全最经典)

其中,博主最推荐的写作方式如下:

为了达到线程安全,又能提高代码执行效率,这里可以采用DCL(Double Check Locking)的双检查锁机制来完成

public class MySingleton {  

    //使用volatile关键字保其可见性
volatile private static MySingleton instance = null; private MySingleton(){} public static MySingleton getInstance() {
try {
if(instance != null){//懒汉式 }else{
//创建实例之前可能会有一些准备性的耗时工作
Thread.sleep(300);
synchronized (MySingleton.class) {
if(instance == null){//二次检查
instance = new MySingleton();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
}

看了看内容确实是这个道理,然后就把这段代码拿来使用了。然后在实际测试中发现,其并没有保证线程安全的问题。

之后在同事的指点下发现,其实上文一段的线程安全仅仅只是在未实例化单例的前提下,以线程安全的方式实例化单例,使之在高并发多线程的环境下有且仅被new过一次。

也就是说,在单例被实例化之后,这段代码是并没有什么作用的。

单例被实例化之后,instance != null一直成立,使getInstance()每次都是return instance。所以,多线程都能拿到指向同一个实例的引用。

所以即使是使用了这种双检查锁机制的代码,依然要对后面要使用到的公用方法做同步,以免出现问题。

而对公用方法做同步的操作也分两种情况。一种是公用方法里只有局部变量,那么此时不做同步也是可以的,因为局部变量只会存在于相应的线程内存里,并不会被其它线程所影响。另外一种是含有成员变量,如果成员变量只有读的操作,那不同步也可以;如果成员变量涉及读写操作,那么就要对相应的方法进行同步了。

局部变量不会受多线程影响
成员变量会受到多线程影响

多个线程应该是调用的同一个对象的同一个方法:
如果方法里无成员变量,那么不受任何影响
如果方法里有成员变量,只有读操作,不受影响
                      存在写操作,考虑多线程影响值

来源:关于多个线程同时调用单例模式的对象,该对象中方法的局部变量是否会受多个线程的影响

最新文章

  1. Linux学习之让进程在后台可靠运行的方法详解
  2. C语言回顾-二维数组
  3. Java虚拟机JVM学习03 连接过程:验证、准备、解析
  4. css中 Span 元素的 width 属性无效果原因及多种解决方案
  5. 使用MVVM框架(avalonJS)进行快速开发
  6. 【虚拟机】苹果虚拟机mac10.11.6+Xcode8.1
  7. JavaScript关闭窗口的同时打开新页面的方法
  8. Java线程池与java.util.concurrent
  9. UVA-11235 Frequent values (RMQ)
  10. Golang官方图片库
  11. TeeChart的X轴为时间,多个Y轴的显示
  12. python的and与or剖析
  13. RabbitMQ 默认端口号
  14. jquery类数组结构学习笔记
  15. Java面试题之基础篇概览
  16. C++版 - UVa1585 Score - 题解
  17. Arduino-接口图
  18. Linux设备驱动程序 第三版 读书笔记(一)
  19. zookeeper配置文件共享中心
  20. Qt编写的开源帖子集合(懒人专用)

热门文章

  1. Yii2.0 安装yii2-queue并在Linux启动守护进程监听消息
  2. polyfill 一个解决兼容的绝佳方案
  3. Linux学习_按时间顺序解压多个文件,搜索文件中的内容
  4. vos限制客户呼出时间
  5. So you want to write a desktop app in Python
  6. Uva 11806 拉拉队
  7. Max answer(The Preliminary Contest for ICPC China Nanchang National Invitational)
  8. chapter1-unions.py
  9. xml中${}的使用含义(美元符号大括号,以Spring、ibatis、mybatis为例)
  10. 前端JavaScript之DOM事件操作