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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© walkonby 中级黑马   /  2013-1-27 21:41  /  1600 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


这个是懒汉式的判断
同样的是每次进来都要判断
加上外面一个判断在不为null的时候还会多判断几次(如果多几个线程还会那么巧的话 )
为什么在外面加if(s==null)这种方式比锁效率更高呢
是单纯的判断null效率比较高还是说锁的判断不是一般的判断
求详细解释下 thank.

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

9 个回复

倒序浏览
我觉得是同步代码块会降速很多   应该尽量避免其他线程接触到同步锁的判断    外层加个判断就能实现这个目的了
回复 使用道具 举报
如果不用外层的if的话,那么每次都会判断synchronized,判断synchronized是很耗资源的。在外层加个if,那么s有了值之后,第一个if都通过不了,就不会去判断synchronized了,保证了性能

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
效率高说的是在对象创建出来以后,如果第一次效率是低的。如果对象不为空的话,下面的锁还有if判断都不用判断了,那是不是效率高了呢。

if(s == null){
  synchronized(Single.class){
     if(s == null)
        s = new Single();
  }
}

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
这样做是为了提高效率。
在多线程中,这样做是为了确保已经获得过一次s的线程不会再去初始化第二次
举例:
  1. /*
  2. * 分析:
  3. * 1、当两个线程同时要对st进行初始化时,当a线程判断st为null时,开始对st进行初始化,a还没有初始化完成b线程也要对st进行初始化,
  4. *   这是判断st也为null,也开始对st进行初始化,这就违背类单例模式的初衷了。所以要在if判断进行同步处理
  5. * 2、进行完同步处理后,线程安全了,但是效率太低。因为每个线程都要等待前一个判断时候为null后,才能进行下一个线程的判断,这样会导致许多线程等待
  6. * 3、由于等待线程太多,这样就会导致效率低,如果在同步代码块前面增加一个判断语句,当st为空,才会进入到同步块,这样就会减少同步块的等待线程数量
  7. */
  8. class SingleThread{
  9.         private static SingleThread st;
  10.         private SingleThread(){}
  11.        
  12.         public static SingleThread getSt(){
  13.        
  14.                 /*
  15.                  * 判断st时候已经实例化完成。
  16.                  * 如果没有完成,那么就执行下面的语句
  17.                  * 如果已经完成初始化,那么就不执行直接返回st
  18.                  */
  19.                 if(st == null){
  20.                         //在第一个线程初始化完成以前,有可能还有线程进来有进行初始化,这是用来把这样的线程挡在外面的
  21.                         synchronized (SingleThread.class) {
  22.                                 //如果st为null就进行初始化
  23.                                 if(st == null){
  24.                                         st = new SingleThread();
  25.                                 }
  26.                         }
  27.                 }
  28.                 return st;
  29.         }
  30. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
黄锦成 发表于 2013-1-27 23:21
如果不用外层的if的话,那么每次都会判断synchronized,判断synchronized是很耗资源的。在外层加个if,那么s ...

学长啊 他这个锁里面的判断是个什么原理啊 其实我估计也是锁比if耗资源 但是他是怎么个耗费资源法的呢
回复 使用道具 举报
张政 发表于 2013-1-28 09:00
学长啊 他这个锁里面的判断是个什么原理啊 其实我估计也是锁比if耗资源 但是他是怎么个耗费资源法的呢 ...

锁有个标识位,好像是0和1。
回复 使用道具 举报
黄锦成 发表于 2013-1-28 10:48
锁有个标识位,好像是0和1。

.. 那个貌似是毕老师打的个比喻啊. 如果真是直接判断0 1 的话 那锁也不是很耗费资源把.
回复 使用道具 举报
张政 发表于 2013-1-28 12:59
.. 那个貌似是毕老师打的个比喻啊. 如果真是直接判断0 1 的话 那锁也不是很耗费资源把. ...

关键是每次只能有一个线程得到锁。如果有n个线程,其中一个线程得到锁,就有n-1个在等待,那么系统性能就降低了。说法有点错了,应该是性能,而不是耗费资源。
回复 使用道具 举报
黄锦成 发表于 2013-1-28 13:04
关键是每次只能有一个线程得到锁。如果有n个线程,其中一个线程得到锁,就有n-1个在等待,那么系统性能就 ...

还是有些疑问 等会QQ上问你把 反正分搞到了 哈哈
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马