java基础之设计模式(1)--单例模式

来源:互联网 发布:新笔下文学软件 编辑:程序博客网 时间:2024/06/16 13:37

先贴出一些概念,对后面的讲解有一定帮助

JMM(java内存模型)

根据JMM的设计,系统存在一个主内存(Main Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。

线程若要对某变量进行操作,必须经过一系列步骤:首先从主存复制/刷新数据到工作内存,然后执行代码,进行引用/赋值操作,最后把变量内容写回Main Memory。Java语言规范(JLS)中对线程和主存互操作定义了6个行为,分别为load,save,read,write,assign和use,这些操作行为具有原子性,且相互依赖,有明确的调用先后顺序。


网上关于单例模式的实现已经很多,一搜一大堆,此处不再赘述,先看代码

public class SingletonClass { 

  private static SingletonClass instance = null


  public static SingletonClass getInstance() { 
    if (instance == null) { 
      synchronized (SingletonClass.class) { 
        if (instance == null) { 
          instance = new SingletonClass(); 
        } 
      } 
    } 
    return instance; 
  } 

  private SingletonClass() { 

  } 

}

以上代码是一个典型的DoubleCheckLock实现的单利模式,相信大家都会写,这里只说问题

1).关于DCL实现的单例模式失效的问题

2).如何实现更好的单例模式


1.关于DCL失效的问题,争论主要是这段代码的问题

if (instance == null) { 

    instance = new SingletonClass(); 


如果线程A执行到 instance = new SingletonClass(),在 new SingletonClass()时为对象分配了内存地址,并将内存地址指向了引用instance,但对象并未完成初始化,只是分配了内存,此时线程B执行到if (instance == null) 发现instance已经存在引用,就会直接被返回,但是这时的对象还未初始化完成,只是分配了内存空间,就造成了线程B拿到的是一个无效的引用对象,这就造成了DCL失效。

以上是参考网上的说法进行理解的,但是根据JMM概念该这样理解:

但是从JAVA2以后,JMM发生了根本的改变,分配空间,初始化,调用构造方法只会在线程的工作存储区完成,在没有向主存储区复制赋值时,其它线程绝对不可能见到这个过程.而这个字段复制到主存区的过程,更不会有分配空间后没有初始化或没有调用构造方法的可能.在JAVA中,一切都是按引用的值复制的.向主存储区同步其实就是把线程工作存储区的这个已经构造好的对象有压缩堆地址值COPY给主存储区的那个变量.这个过程对于其它线程,要么是resource为null,要么是完整的对象.绝对不会把一个已经分配空间却没有构造好的对象让其它线程可见

个人觉着上面的理解是正确的。所以在java2之后就不会存在DCL失效的情况。

2.如何更好的实现单例

1)在判断为空的对象上加violatile关键字。violatile:线程在每次使用变量的时候,都会读取变量修改后的最的值

2)使用静态内部类实现单例,这也是很多地方推荐的

public class SingletonClass { 

  private SingletonClass() { 

  } 

  publicSingletonClass getInstance(){

     return ClassInner.instance;

  }

  private class ClassInner(){

     private static SingletonClass  instance = new SingletonClass();

  }

}

单例模式的分析到这就结束了,第一次写blog,语言组织有待加强,希望以后会更好吧


1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑下载过播放器还是不播放怎么办 局域网内的电脑无法互相访问怎么办 浏览器拖动滑动线页面会跳动怎么办 在暴风影音上视频播放不出来怎么办 格式工厂转换格式占内存太大怎么办 手机登陆不上路由器管理界面怎么办 新路由器设置密码后不能上网怎么办 更换网络后无线路由器不能用怎么办 手机登录不了路由器登录业面怎么办 海康威视通道用户被锁定怎么办 无线适配器或访问点有问题怎么办 客户买鞋子说价格贵该怎么办 小米5s刷成真砖后怎么办 手机电源键坏了开不了机怎么办 手机开关键坏了开不了机怎么办 vivo手机解屏密码忘了怎么办 小米max关机后开关键坏了怎么办 联想手机刷机失败无限重启怎么办 红米2a显示白屏怎么办 小米6手机一直处于开机状态怎么办 怎么在手机上看wifi密码怎么办 怎么查自己的宽带密码忘记了怎么办 怎么查自己宽带账号密码忘了怎么办 电脑重置路由器密码连不上网怎么办 e盘和f盘没有了怎么办 复制文件过程中自己卡住了怎么办 电脑卡住了怎么办 鼠标也点不动 善领wifi连上网不能用怎么办 苹果手机软件更新后网速太慢怎么办 装了固态硬盘开机还慢怎么办 华为荣耀8青春版玩游戏卡怎么办 光猫自带wifi网络很差怎么办 侠盗猎车手自由城之章卡退怎么办? 夏天带头盔晃眼睛太厉害怎么办 别人把钱误转我卡上我怎么办? 家里预留的的网线太短怎么办 电信路由器坏了网线接口断了怎么办 数据线充手机的接头处断了怎么办 新买的小米手环充不进去电怎么办 绝地求生手游被队友故意炸死怎么办 一加3t屏幕开了怎么办?