synchronized(singleton.class)和synchronized(obj)之间的区别

5t7ly7z5  于 2021-07-09  发布在  Java
关注(0)|答案(4)|浏览(515)

使用以下两个版本的单例类有什么区别
首先,我使用synchronized(singleton.class)
在第二个示例中,我使用synchronized(obj)//第一个类型的公共类singleton{

private static Singleton obj = null;

Singleton() {
}

public static Singleton getInstance() {

    synchronized(Singleton.class){
        if (obj == null) {
        obj = new Singleton();
    }
}
    return obj;
}

}
//第二类

public class Singleton {

private static Singleton obj = null;

Singleton() {
}

public static Singleton getInstance() {

    synchronized(obj){
        if (obj == null) {
        obj = new Singleton();
    }
}
    return obj;
}
}
yfjy0ee7

yfjy0ee71#

它们实际上是相同的,而且是一个糟糕的实现,因为obj为null(在您的示例中)并且代码每次调用都是单线程的。它应该使用双重检查锁。。。
第二个应该是:

public class Singleton {
   private static object syncRoot = new object();
   private static Singleton obj = null

   Singleton() {
   }

   public static Singleton getInstance() {

      if ( obj == null ){
        //ONLY SINGLE THREAD IF obj == null
        synchronized(syncRoot){
          if ( obj == null ){
             obj = new Singleton();            
          }
        }
      }
      return obj;
   }
}
ep6jt1vc

ep6jt1vc2#

第二个版本尝试在上同步 null ,将失败。这个 synchronized 关键字尝试获取 Object 引用人 obj ,因为它最初是 null ,您将获得 NulPointerException .

gc0ot86w

gc0ot86w3#

当您使用synchronized(singleton.class)时,只有在第一次创建示例之前才会应用同步,当我们有可能在代码中运行多个线程时才会使用同步。if循环将负责在已有示例可用的情况下不创建另一个示例,通过使用这种同步方式,我们减少了大量的开销,因为我们知道同步类在时间/等待方面会增加开销。

bttbmeg0

bttbmeg04#

主要区别在于 synchronized(obj) 不起作用:你第一次叫它, objnull ,所以你会看到 NullPointerException .
在ideone上演示。 Singleton.class 另一方面,它永远不会 null ,因此可以使用它进行同步。但是,恶意代码可以执行一种攻击,使您的 getInstance 方法永远等待:他们只需要锁定你的 Singleton.class ,在那里无限的等待。
针对此攻击的常见防御方法是为锁使用单独的私有静态对象,如下所示:

public class Singleton {

    private static Singleton obj = null;
    private static final Object syncRoot = new Object();

    Singleton() {
    }

    public static Singleton getInstance() {
        synchronized(syncRoot){
            if (obj == null) {
                obj = new Singleton();
            }
        }
        return obj;
    }
}

相关问题