(49)静态同步函数的锁是Class对象,例子:懒汉式--在多线程中存在问题--同步解决

一、如果同步函数被静态修饰后,使用的锁是什么呢?
通过验证,发现使用的不是this.因为静态方法中也不可以定义this
静态进内存,内存中没有本类对象,但是一定个该类对应的字节码文件对象。
类名.class 该对象的类型为Class.
静态的同步方法,使用的锁是该方法所在类的字节码文件兑现,类名.class
二、懒汉式—-在多线程中存在安全问题

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

这个静态方法被run调用后,存在安全问题原因:
s是个共享数据,当一个线程执行到if(s==null)时,判为真时,cpu执行其他的程序去了,比如此时另一个线程,此时执行if(s==null),因为刚才的线程并没有创建对象,所以判断为真,这样就会创建两个对象,存在安全问题

将此函数改为同步函数,就可以解决这个问题。
class Single
{
private static Single s=null;
private Single(){}
public static synchronized Single getInstance(){
if(s==null)
s=new Single();
return s;
}
}

但是这样会使得多线程运行效率低,原因是加锁多个判断条件。

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中也要写个if(s==null)呢?
举个栗子说明:
第一个线程在外层if判断成功后,进入同步块,判断内部的if,成立,此次CPU被剥夺,比如执行到第二个线程,同样判断外层的if,因为上同步块上着锁,进不了,隔一段时间,第一个线程得到cpu,继续执行,创建了对象,开锁。然后隔一段时间,第二个线程继续执行,进入共享区,然后if(s==null)判断失败,开锁,这就防止了创建对个对象。因为只有一个对象,所以以后的外层if (s==null)
都判断失败,因为已经有对象了,这样就摆脱了在多线程中使用同步方法、,每次都判断是否有锁,运行效率有所提高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值