• 单例模式之懒汉的并发问题


    饿汉模式:

    class Single{

      private staitc final Single s= new Single();

      private Single(){}

      public static Single getSingle(){

        return s;

      }

    }  

    懒汉模式:

    class Single{

      private static Single s= null;

      private Single(){}

      public static Single getSingle(){

        if(s == null){

            -->A线程

            -->B线程

          s  =  new Single();

          return s;

        }  

      }

    }  

    在这里使用懒汉模式有一个安全性问题:

    就是s为共享数据,可能会并发的访问getSingle()方法。当多线程访问时,一个A线程进来后,可能调用了sleep()方法在这里沉睡;一个B线程也可能在沉睡,当A线程醒来后,就会new一个对象,B线程醒来也会new一个对象;这样就不符合我们单例模式的特点了。

    解决方案:在getSingle()方法前增加synchronized进行同步

    另一个问题,当加了synchronized后,那么很多线程来访问时,都要判断一下锁是哪个,这就造成速率下降,解决方案如下:

    public staitc Single getSingle(){

      if(s == null){

        synchronized(Single.class){  -->B线程,等着A解锁才让进去

          if(s == null){

              -->A线程

            s = new Single();

          }

        }

      return s;

      }

    }

    思路:

    当s == null时,A线程进来了,他加了一下锁后进入第二个if(s ==null){},然后沉睡;此时,B也通过了第一个if(s == null),当B玩下执行时,遇到了synchronized(),发现这里A进行了加锁,没办法B线程只能等着,等A把锁解了。此时,A线程醒来了,它new 了一个对象后,继续玩下执行,然后把锁解了,这是s不等于null了。B发现A解锁了,它继续往下执行,发现s不等于null了,那它直接返回了A创建的那个对象s。当c线程访问getSingle方法时,只需判断s是否为null,而不用去判断锁对象了。因为s不等于null了,所以直接返回对象,这样就提高了效率

    懒汉模式是延迟加载的实例,面对多线程访问时,需要进行同步代码块,为了增加效率,又要使用双重判断

    注意:非静态的同步函数对象是this,静态的同步函数对象是:字节码对象。即类.class;

    Java小生店铺:

    Pc端:http://shop125970977.taobao.com/index.htm

    手机端:搜索 java小生店铺

    希望店铺的资料能帮助到你!!!

     

  • 相关阅读:
    案例------存储过程
    案例------冒泡排序
    案例------递归调用
    天气预报接口api(中国天气网)
    【转】ubuntu64,ndk-r9 编译 ffmpeg 2.1.1的config文件
    android权限大全
    JNI 回调小记
    java设置环境变量小工具
    bootstrap之双日历时间段选择控件—daterangepicker(汉化版)
    一个 bootstrap 弹出框插件
  • 原文地址:https://www.cnblogs.com/lirenzhujiu/p/5926190.html
Copyright © 2020-2023  润新知