zoukankan      html  css  js  c++  java
  • 【Java学习笔记】线程安全的单例模式及双重检查锁—个人理解

    搬以前写的博客【2014-12-30 16:04】

    在web应用中服务器面临的是大量的访问请求,免不了多线程程序,但是有时候,我们希望在多线程应用中的某一个类只能新建一个对象的时候,就会遇到问题。

    首先考虑单线程,如果要求只能新建一个对象,那么构造函数我们要设为private。简单的想法:
    class singleton{
      private singleton(){
        //.....
      }
      private static singleton instance;
      public static singleton getinstance(){
        if(instance==null)            //1
        instance = new singleton();  //2
        return instance
      }
    }
    这对于单线程是合理的,第一次调用singleton类时,会新建出singleton对象,但之后访问时,返回的是第一次新建的instance。
    但多线程访问时,有可能同时进入//1处的条件判断,多次执行2代码,从而新建多个singleton对象。我们考虑使用同步关键字sycronized
    class singleton{
      private singleton(){
        //.....
      }
      private static singleton instance;
      public static singleton synchronized getinstance(){
        if(instance==null)            //1
          instance = new singleton();  //2
        return instance
      }
    }
    此时可以保证不出错,是单例模式的一种方案,但是问题是每次执行都要用到同步,开销较大。
    另外一种想法是,双重检查锁,代码如下:
    class singleton{
      private singleton(){
        //.....
      }
      private static singleton instance;
      public static singleton  getinstance(){
        if(instance==null) {           //1
          sycronized(singleton.class){
            if(instance==null)
              instance = new singleton();  //2
           }
        }
        return instance;
      }
    }
    此写法保证了,当多个进程进入第一个判断锁时,会被同步机制隔离,只有一个程序进入新建对象,再其他线程进入时,instance已经不为null,因此不会新建多个对象。这种方法就叫做双重检查锁,但是也有一个问题,就是java是实行无序写入的机制,在某个线程执行//2代码的过程中,instance被赋予了地址,但是singleton对象还没构造完成时,如果有线程访问了代码//1此时判断instance不为空,但是方法返回的是一个不完整对象的引用。此时可能会产生错误!
    另外一种实现单例模式的写法就是
    class singleton{
      private singleton(){
        //.....
      }
      private static singleton instance = new singleton();
      public static singleton  getinstance(){
        return instance;
      }
    }
    这样就不会有之前的问题了。
  • 相关阅读:
    如何使员工能力和收入相匹配?
    微软Windows Phone 7新特性详解
    微软MSDN中文网络广播(Webcast)——Visual Studio 2010 & ALM应用实践系列课程预告(2011)
    博客园开发征途新书《我也能做CTO之.程序员职业规划》出版
    架构抉择:享用微软SQL云平台就像吃烤鸭
    微软北京.NET俱乐部免费活动(2010年7月18日)–Visual Studio 2010 敏捷开发与云计算Azure
    WCF与Hprose在微软云计算平台Azure上的对决
    在Visual Studio 2010中实现数据驱动Coded UI Tests
    基于微软Dryad分布式并行计算平台云技术的研究
    微软Visual Studio 2010架构设计功能应用
  • 原文地址:https://www.cnblogs.com/jugg1024/p/4204965.html
Copyright © 2011-2022 走看看