A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 钟伟杰 中级黑马   /  2013-4-16 22:46  /  1863 人查看  /  4 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 钟伟杰 于 2013-4-17 10:41 编辑

class Single
{
      private static Single s = null;
       private Single(){};
       public static Single getInstance()
       {
              if(s==null)
              {
                     synchronized(Single.class)
                     {
                            if(s==null)
                                   s = new Single();
                     }
              }
              return s;
       }
}

关于这个懒汉式的synchronized,public static synchronized Single getInstance()这种加锁方法明白,但是上面的方法不理解,总不知道如何分析synchronized添加在哪里。
synchronized应该如何使用,最好带上分析的思路,谢谢.

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

4 个回复

倒序浏览
首先synchronized的使用很简单 就是在放在需要同步的代码快中,让后知道什么时候用什么样的锁就行了。但是楼主上面说的那种延迟加载的单例模式很特殊,里面使用了双重判断,所以感觉很晕。
代码如果这样写,这个会先判断s是否等于null,如果为空则进去new 一个Single对象。这样的代码在多线程中是有安全隐患的,因为变量s是共享数据,而且有两句代码都操作了s这个变量。
    if(s==null)
              {
                      //如果一个线程运行到这里刚好被切换,另一个线程也进来,同时也满足if判断,如果两个线程都执行完后都会返回一个Single对象,这时也不会保证对象的唯                 一了。
                    s=new Single();
              }
              return s;
这时需要同步
synchronized(Single.class)//因为getInstance()是静态方法,所以需要用到Single的字节码文件锁
                     {
                            if(s==null)
                                   s = new Single();
                     }
其实想上面这样写,代码已经没有问题了。但是如果每次调用这个方法的话都会去同步和判断锁,是很浪费资源的。所以在外面再判断一次。如果s不为空了后,直接返回,就不会进入到同步代码块中,所以第一个判断完全是为了代码执行效率。
if(s==null)
              {
                     synchronized(Single.class)
                     {
                            if(s==null)
                                   s = new Single();
                     }
              }

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
同步代码块
回复 使用道具 举报
谭威 发表于 2013-4-17 02:19
首先synchronized的使用很简单 就是在放在需要同步的代码快中,让后知道什么时候用什么样的锁就行了。但是 ...

学习了,非常感谢
回复 使用道具 举报
同时学习一下
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马