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

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

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

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

为了达到线程安全,又能提高代码执行效率,这里可以采用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-多线程与单例的更多相关文章

  1. Java 多线程之单例设计模式

    转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...

  2. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  3. Java设计模式之单例

    一.Java中的单例: 特点: ① 单例类只有一个实例 ② 单例类必须自己创建自己唯一实例 ③ 单例类必须给所有其他对象提供这一实例 二.两种模式: ①懒汉式单例<线程不安全> 在类加载时 ...

  4. Java复习11. 单例编程

    Java复习11. 单例编程 1.最简单的写法,那个方式是线程不安全的 public class Singleton {     private static Singleton instance; ...

  5. java中的单例设计模式

    单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供 ...

  6. Java开发之单例设计模式

    设计模式之单例模式: 一.单例模式实现特点:①单例类在整个应用程序中只能有一个实例(通过私有无参构造器实现):②单例类必须自己创建这个实例并且可供其他对象访问(通过静态公开的访问权限修饰的getIns ...

  7. Java笔记(十一)……单例设计模式

    设计模式 解决某一类问题最行之有效的方法 Java中有23中设计模式 单例设计模式 解决一个类在内存中只存在一个对象 思路 将构造函数私有化 在类中创建一个本类对象 提供一个方法可以获取到对象 两种方 ...

  8. java设计模式_单例

    public class Singleton { public static void main(String[] args) throws Exception { System.out.printl ...

  9. 转载:java基础之单例

    转载:https://blog.csdn.net/goodlixueyong/article/details/51935526 https://www.cnblogs.com/cielosun/p/6 ...

  10. java基础28 单例集合Collection下的List和Set集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

随机推荐

  1. pure-ftp 修改用户信息

    1.修改用户test的密码 [root@localhost bin]# ./pure-pw passwd test #修改密码 Password: Enter it again: [root@loca ...

  2. OpenGL学习 Introduction

    OpenGL and Graphics Pipeline The word pipeline is from production lines in factories.Generating a pr ...

  3. CRSF在ASP.NET CORE MVC 的处理方式

    https://www.cnblogs.com/catcher1994/p/6720212.html

  4. 【转】Android 组件系列-----Activity保存状态

    本篇随笔将详细的讲解Activity保存状态的概念,也就是saving activity state. 一.Activity状态保持概念 保存Activity的状态是非常重要的,例如我们在玩一个游戏的 ...

  5. python 3+djanjo 2.0.7简单学习(四)--Django视图

    1.概念 Django 中的视图的概念是「一类具有相同功能和模板的网页的集合」.比如,在一个博客应用中,你可能会创建如下几个视图: 博客首页——展示最近的几项内容. 内容“详情”页——详细展示某项内容 ...

  6. redux详解

    redux介绍 学习文档:英文文档,中文文档,Github redux是什么 redux是一个独立专门用于做状态管理的JS库(不是react插件库),它可以用在react, angular, vue等 ...

  7. Search in Rotated Sorted Array——LeetCode

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  8. javaScript校验图片大小、格式

    1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...

  9. matlab时间测试

    因为想把样本筛选一下,所以简单的分类器先跑了一下,没想到跑完分类器在对样本筛选时的时间大大超过了样本进分类器的时间,这个显然不能达到我要的节省时间目的.于是分析了一下matlab中各个环节的时间成本, ...

  10. WebSeal单点登陆

    WebSeal单点登陆 作为学习整理,部分内容来自网络和官方文档. LDAP LDAP可以看作一种数据库,分为客户端和服务端.服务端是用来存放资源,客户端用来操作资源.它是一种树形存储结构,遍历起来会 ...