黑马程序员技术交流社区
标题:
多线程对懒汉式的效率低下的解释
[打印本页]
作者:
Jim-剣◆﹏
时间:
2013-9-27 13:42
标题:
多线程对懒汉式的效率低下的解释
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
return s;
}
}
复制代码
加上锁可以解决安全问题,但是由此又导致了此段代码的执行效率低下,因为每次线程进来前都需要判断锁有没有开着,如果开着就线程就进入方法体,如果锁没开,问题一是:此时应该是返回对象S呢还是执不执行return s,我认为此时不执行,而是cpu执行权让出去,我理解对不对
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;
}
}
复制代码
判断之前增加一个if判断语句,如果为空,才进行锁判断,否则不进行锁判断,直接取走对象,问题还是一样,如果此时取走对象,对象还没建立会出现什么问题?
问题二:为什么这个能够解决效率问题?增加IF判断之后,线程每次进去之前要判断
synchronized(Single.class)情况变为了判断IF语句而已,还是要判断,还是这两个语句的执行本身存在效率问题,例如执行IF语句需要1ms,而synchronized需要5ms这种?
作者:
jìng╮煜
时间:
2013-9-27 14:04
本帖最后由 jìng╮煜 于 2013-9-27 14:11 编辑
可以像你这么理解,问题一,在同步代码块锁住的情况下,其他线程进入应该是需要wait的.(修改一下,不需要wait,因为此语句没有在synchronized 下)
问题二.关于锁,其实一个synchronized(Single.class)是一个方法,还要执行一串代码.(我估计是这样的) 如果是一个if,就仅仅是判断,仅仅是它本身而已.时间所耗长短自然就能看得出来
作者:
code_geass
时间:
2013-9-27 14:05
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)//第一个判断不是说对象有问题,而是为了提高效率,因为每次都要判断锁。如果对象已经建立就直接返回s。
{
synchronized(Single.class)//同步是解决安全问题
{
if(s==null)//如果为空才建立对象,都是为了安全。
s = new Single();
}
}
return s;
}
}
复制代码
作者:
Jim-剣◆﹏
时间:
2013-9-27 14:09
我思考了好一会,说说我的理解,引大神:
其实我觉得这个效率的问题是针对大并发量来说的,如果是小并发,在效率上不会有什么差别。
我们可以分析一下,两者的区别就在于:前者每次执行都存在两种情况(1)判断锁,(2)判断锁+判断if,
后者只需要在第一次创建完毕是要判断if+判断锁+判断if,以后都只存在判断if
当有大并发量的时候,前者的叠加效应会加大这个负担,而后者不存在叠加效应或者可以忽略不计
再者把一个大的方法声明为synchronized也会大大降低效率(此处来源某博客,具体可能涉及底层)
而对于执行不执行Return S,还没弄清
作者:
杨增坤
时间:
2013-9-27 14:53
第一种:应该不会立即执行return,而是线程等待,等待锁被释放。
第二种:就会执行return,因为一判断不为空,就说明此对象已经创建,不需要创建,直接返回已经创建好的对象即可。省去了判断锁
希望对你有帮助!
作者:
.只影、天涯.
时间:
2013-9-29 17:09
前一段程序的问题,如果锁没开,其他线程是出于等待状态的。等待拿到锁的线程执行同步结束后释放cpu执行权。
后一段程序的问题:
判断之前加上if判断语句,如果第一次判断为空的话,某一线程必须会往下执行直到创建一个对象:对象没有被创建,又怎么会有被取走的可能。
能解决效率问题是:因为创建对象需要在堆内存中开辟空间并且对对象进行初始化,程序执行到才创建对象,可以节约内存资源。如果执行到后第一次某一线程创建了对象,下一次某一线程执行则判断如果对象存在就直接使用对象,就不必拿到锁后再去进行对象是否存在的判断。
作者:
周志龙
时间:
2013-9-29 18:38
饿汉初始化根本不会存在线程安全问题,但开销是个问题,因为懒汉模式的使用理念是"用时才初始化",饿汉模式则是"不管用不用都初始化",这本身是和业界流行的资源使用习惯相违背的.
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2