Java-多线程与单例
最近在公司写需求时遇到了多线程与单例一同出现的情况。
这个时候想到的就是线程安全以及单例的定义了,虽然单例指的是在内存中它只有一份,但是并不是说就是线程安全的。
所以,我当时就到网上找了关于多线程下单例的线程安全问题的资料,然后就知道如下博客:高并发下线程安全的单例模式(最全最经典)
其中,博主最推荐的写作方式如下:
为了达到线程安全,又能提高代码执行效率,这里可以采用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。所以,多线程都能拿到指向同一个实例的引用。
所以即使是使用了这种双检查锁机制的代码,依然要对后面要使用到的公用方法做同步,以免出现问题。
而对公用方法做同步的操作也分两种情况。一种是公用方法里只有局部变量,那么此时不做同步也是可以的,因为局部变量只会存在于相应的线程内存里,并不会被其它线程所影响。另外一种是含有成员变量,如果成员变量只有读的操作,那不同步也可以;如果成员变量涉及读写操作,那么就要对相应的方法进行同步了。
局部变量不会受多线程影响
成员变量会受到多线程影响多个线程应该是调用的同一个对象的同一个方法:
如果方法里无成员变量,那么不受任何影响
如果方法里有成员变量,只有读操作,不受影响
存在写操作,考虑多线程影响值
Java-多线程与单例的更多相关文章
- Java 多线程之单例设计模式
转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- Java设计模式之单例
一.Java中的单例: 特点: ① 单例类只有一个实例 ② 单例类必须自己创建自己唯一实例 ③ 单例类必须给所有其他对象提供这一实例 二.两种模式: ①懒汉式单例<线程不安全> 在类加载时 ...
- Java复习11. 单例编程
Java复习11. 单例编程 1.最简单的写法,那个方式是线程不安全的 public class Singleton { private static Singleton instance; ...
- java中的单例设计模式
单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供 ...
- Java开发之单例设计模式
设计模式之单例模式: 一.单例模式实现特点:①单例类在整个应用程序中只能有一个实例(通过私有无参构造器实现):②单例类必须自己创建这个实例并且可供其他对象访问(通过静态公开的访问权限修饰的getIns ...
- Java笔记(十一)……单例设计模式
设计模式 解决某一类问题最行之有效的方法 Java中有23中设计模式 单例设计模式 解决一个类在内存中只存在一个对象 思路 将构造函数私有化 在类中创建一个本类对象 提供一个方法可以获取到对象 两种方 ...
- java设计模式_单例
public class Singleton { public static void main(String[] args) throws Exception { System.out.printl ...
- 转载:java基础之单例
转载:https://blog.csdn.net/goodlixueyong/article/details/51935526 https://www.cnblogs.com/cielosun/p/6 ...
- java基础28 单例集合Collection下的List和Set集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...
随机推荐
- python-daemon
http://legacy.python.org/dev/peps/pep-3143/#python-daemon install yum install python-daemon example ...
- 通过Exception获取其中的信息
private static String getCrashMessage(Exception ex) { Writer writer = new StringWriter(); Pri ...
- PHP判断变量是否小数并对小数进行处理
/*判断是否为小数demo*/$a = 1.2; if(is_int($a)){ echo "$a 是整数!"; }else{ echo "$a 不是整数!"; ...
- 特殊矩阵的压缩存储(转自chunlanse2014)
对称矩阵 对于一个矩阵结构显然用一个二维数组来表示是非常恰当的,但在有些情况下,比如常见的一些特殊矩阵,如三角矩阵.对称矩阵.带状矩阵.稀疏矩阵等,从节约存储空间的角度考虑,这种存储是不太合适的.下面 ...
- POJ-3111 K Best---二分求最大化平均值
题目链接: https://cn.vjudge.net/problem/POJ-3111 题目大意: 卖宝救夫:Demy要卖珠宝,n件分别价值vi 重 wi,她希望保留k件使得 最大. 解题思路: # ...
- BestCoder Round #91 1002 Lotus and Horticulture
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6012 题意: 这几天Lotus对培养盆栽很感兴趣,于是她想搭建一个温室来满足她的研究欲望. Lotus ...
- 轻量级HTTP服务器Nginx(常用配置实例)
轻量级HTTP服务器Nginx(常用配置实例) 文章来源于南非蚂蚁 Nginx作为一个HTTP服务器,在功能实现方面和性能方面都表现得非常卓越,完全可以与Apache相媲美,几乎可以实现Apa ...
- 2018.8.25 JVM
一.JVM内存区域 Java虚拟机在运行时,会把内存空间分为若干个区域,根据<Java虚拟机规范(Java SE 7 版)>的规定,Java虚拟机所管理的内存区域分为如下部分: 方法区 堆 ...
- Qlikview 数据加载方法罗列
以下是通常会用到的数据加载的方法,供大家参考: 1. 从文件加载: Data: Load *,RowNo() as InputKey; SQL SELECT ID,TEST,DATECREATED F ...
- Vuex进阶
1.插件 下面以一个对state进行持久化存储的插件为例进行介绍: 代码结构: saveInLocal.js export default function (store) { if (localSt ...