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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李红飞 中级黑马   /  2012-5-26 22:30  /  2708 人查看  /  7 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

1:
class Single
{
        private static Single s = null;
        private Single(){}
        public static  Single getInstance()
        {
                if(s==null)
                {
                               
                }
                return s;
        }
}
2:
class Single
{
        private static Single s = null;
        private Single(){}
        public static synchronized  Single getInstance()
        {
                if(s==null)
                {
                       
                        s = new Single();
                }
                return s;
        }
}
3:
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;
        }
}
视频讲解上说明懒汉模式有以上3种,我一直不明白第三个程序要两次判断s==nul的含义,
而且线程之间切换感觉十分不清晰?请高手解答!!!

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

7 个回复

倒序浏览
其实老师说了如果只进行一次判断也是可以的只不过这样就和第二种一样了(第二种是同步函数,如果判断一次第三种就成了同步代码块,基本就一样了),之所以要判断两次if是为了提高效率,譬如有5个线程都要用到s,假设A先执行,判断第一个if后获得锁在判断第二个if后失去执行权,这时b进来判断第一个if后发现所被占用所以等待,这时a醒来建立s对象,释放锁,b进来判断第二个if不符合,不创建对象直接返回s,以后c、d、e等其他线程再进来判断第一个if不符合就不会判断锁了(判断if比判断锁效率高),这样就提高了效率,而第二种不论是否创建了s对象,每一个调用这个方法的线程都要判断锁,而第三种把他改为只要有一个线程创建了s对象,那么以后所有调用这个方法的线程都不用判断锁了,直接就被if干掉了。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 龚正军 于 2012-5-27 02:13 编辑


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;
        }
}
视频讲解上说明懒汉模式有以上3种,我一直不明白第三个程序要两次判断s==nul的含义,--------------------------------这是关键点因该分成两个问题答,为什么要两次判定??两次判定有何好处??
而且线程之间切换感觉十分不清晰?请高手解答!!!--------------------------------------------------------------------------------如果了解上面两点再来看这问题就很简单了。



--------------------------------------------割掉---------------------------------------------------

第一个问题:为什么要两次判定:这个问题很简单:为了让对于锁(也就是对象)的判定改成简单的if条件语句判定!  if(s==null)第一个判定的时候,任何一个对象(比如A,B,C,D这4个对象都想往下走,但是他们遇到的第一个条件是判定S==NULL这个条件语句。
然后才是synchronized(Single.class) 这个锁,那么在第一个条件他们除了一个进来比如是D,(当D进来后,其他都进不来了)所以其实他们都不需要再判定synchronized(Single.class)这个锁了,就达到我们的目的了!

第二个问题:这么判定有什么好处??这要说到synchronized(Single.class)这个锁的判定,(这点我简单说明下,其实所有的锁为什么独一无二,对于计算机来说判定是相当繁琐的一个过程,(不太恰当的例子:比如"12ad"这个对象,计算机把'1'+'2'+'a'+'b'代表的数字相加来判定他与其他对象的不同,但还没完,如果他们数字是否相同也有可能,于是有一系列相对繁琐的判定---------这就构成了很浪费效率的无畏浪费),但是如果把它换成一个简单的if条件语句判定,那在大数据处理时是相当的节约时间和计算机效率的。
------------------------------------好处就是:不再浪费资源!

那么在理解上面两点后,再看后面的问题就简单了!

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
哈哈,其实理解起来很简单,也不需要想太多我就跟你说说第三个例子:
同步代码块里面是保证单线程运行(不可能有多个线程在这里面执行),它里面的if是判断作用是给进入外面if语句但在同步代码块外面等待线程用的(就那么一个作用)
外面的if判断是创建了对象后,给后面的进程使用的,目的在于绕过同步代码块直接返回对象,可以提高效率嘛!
不知道这样回答能不能帮助你理解

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
同步代码块里面是保证单线程运行(不可能有多个线程在这里面执行),它里面的if是判断作用是给进入外面if语句但在同步代码块外面等待线程用的(就那么一个作用)
回复 使用道具 举报
同步代码块里面是保证单线程运行(不可能有多个线程在这里面执行),它里面的if是判断作用是给进入外面if语句但在同步代码块外面等待线程用的(就那么一个作用)
回复 使用道具 举报
楼主应该要好好理解一下static这个修饰字; s由static修饰,一旦某个对象对s赋新值 ,s就会改变;   现在如果第一个线程进来 它就已经使s=new Single() ; 这样的话,对于第一个s==null条件,接下来所有线程都不满足,也就不会再去执行里面的代码,这样做效率就提高 了。   对于要用到第二个s==null的条件是:已经多个线程都执行过了第一个s==null语句, 其中由于锁的作用,只能有一个进入同步代码中,  当这个锁被释放时,外面等候的线程就一个一个的进来  ,都会去判断(s==null) ;      
回复 使用道具 举报
郭宁 中级黑马 2012-5-27 13:11:23
8#
我一直在考虑怎么用最简单词句来阐述最明白的道理~哈哈
  1. if(s==null)//如果为空,说明已经有实例了,直接返回就是啦,无需考虑同步并发的问题
  2.                 {   //反则 就要创建一个实例,创建实例的时候就要考虑 同步的并发的问题,
  3. //外加一层判断的作用就是免去了  实例已存在 这种情况的同步问题
  4.                         
  5.                         synchronized(Single.class)
  6.                         {                                
  7.                                 if(s==null)
  8.                                        
  9.                                         s = new Single();
  10.                         }
  11.                 }
  12.                 return s;
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马