同步方法或同步块:在Java编写Singleton类时,哪一个更好



正如我们在创建单顿类同步操作时所知道的,我们将整个方法作为同步或仅是负责创建对象同步的语句的块。但是,在这两种方法中,更好,为什么?

方法1

public static A getA(){  
    if (obj == null){  
        synchronized(Singleton.class) {
            if (obj == null) {
                obj = new Singleton();//instance will be created at request time  
            }  
        }   
    }  
    return obj;  
} 

方法2

public synchronized static A getA(){  
    if (obj == null){  
        obj = new Singleton();//instance will be created at request time  
    }   
    return obj;  
} 

概念:

public synchronized static A getA(){  
    if (obj == null){  
        obj = new Singleton();//instance will be created at request time  
    }   
    return obj;  
} 

在方法上使用同步关键字(如上面的示例)同步对整个方法的访问,这通常是很安全的,但是除非您有很小的方法,否则您可能会同步一块代码,而不是绝对需要的代码。到,这更多的是性能。因为一次只能通过一个线程访问同步块/方法,所以它们确实会减慢处理。您同步的一大块代码越大,性能命中率就越好。

如果您仅需要一个懒惰的单个资源,则需要做类似的事情:

class MyClass {
      private static volatile Resource resource;
      private static final Object LOCK = new Object();
      public static Resource getInstance() {
            if(resource == null) { 
                synchronized(LOCK) { // Add a synch block
                    if(resource == null) { // verify some other synch block didn't
                                           // write a resource yet...
                        resource = new Resource();
                    }
                }
            }
            return resource;
      }
 }

这里重要的是volatile修饰符,为应用程序中的整个线程提供可见性。

第一个更好,因为当obj不为null时,您不会获得锁,而第二种方法每次都会获取锁。

我会拿第一个,它具有双检查锁定。

也许您也可以尝试这样的事情:

public class MySingleton {
       private static instance = new MySingleton ();
       private MySingleton (){ }
       public MySingleton getInstance {
            return instance;
       }
 }

您最好使用"持有人成语"

public class HolderFactory {
   public static Singleton get() {
      return Holder.instance;
   }
   private static class Holder {
     public static final Singleton instance = new Singleton();
   }
}

这很懒惰,因为将在第一次调用get()时创建实例,并且它是线程安全的,因为类别可以通过classloader加载单个线程中的类。您也可以检查此链接以获取有关单元和线程安全的更多详细信息:https://shipilev.net/blog/2014/saf-public-construction/

相关内容

最新更新