黑马程序员技术交流社区

标题: 如何判断synchronized在哪里使用 [打印本页]

作者: 钟伟杰    时间: 2013-4-16 22:46
标题: 如何判断synchronized在哪里使用
本帖最后由 钟伟杰 于 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应该如何使用,最好带上分析的思路,谢谢.
作者: 谭威    时间: 2013-4-17 02:19
首先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();
                     }
              }
作者: 冯超    时间: 2013-4-17 08:10
同步代码块
作者: 钟伟杰    时间: 2013-4-17 09:08
谭威 发表于 2013-4-17 02:19
首先synchronized的使用很简单 就是在放在需要同步的代码快中,让后知道什么时候用什么样的锁就行了。但是 ...

学习了,非常感谢
作者: Sword    时间: 2013-4-17 10:21
同时学习一下




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2