zoukankan      html  css  js  c++  java
  • 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。所以,多线程都能拿到指向同一个实例的引用。

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

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

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

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

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

  • 相关阅读:
    Ajax和Jsonp的工作原理,以及区别。
    git与GitHub
    Cookie的作用以及封装的方法
    关于angular-route后获取路由标签的一些问题
    javascriptDOM节点
    字符串转化为对象的方法
    将"goOd gooD stUdy dAy dAy up"每个单词的首字母转换成大写其余还是小写字母
    利用HashSet对list集合去重
    集合之Iterator迭代器
    java常用API之System类
  • 原文地址:https://www.cnblogs.com/kumu/p/6921954.html
Copyright © 2011-2022 走看看