正如我们在创建单例类时所知道的同步操作一样,我们将整个方法设置为同步或仅将负责创建对象的语句块作为synchronized.But,这两种方法中哪一个更好,为什么?
方法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;
}
答案 0 :(得分:1)
第一个更好,因为当obj
不为空时你没有获得锁定,而第二个方法每次都获得锁定。
答案 1 :(得分:1)
<强>概念强>
public synchronized static A getA(){
if (obj == null){
obj = new Singleton();//instance will be created at request time
}
return obj;
}
在方法上使用synchronization关键字(如上例所示)同步对整个方法的访问,这通常是非常安全的,但除非你有一个非常小的方法,否则你可能正在同步一大块代码而不是你绝对需要的to,这更像是一个不必要的性能。因为同步块/方法一次只能由一个线程访问,所以它们确实会降低处理速度。您同步的代码块越大,性能就越差。
如果您只需要一个延迟加载的资源,则需要执行以下操作:
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
修饰符,为您应用中的整个主题提供可见性。
答案 2 :(得分:1)
我会选择第一个,它具有双重检查锁定。
也许你也可以尝试这样的事情:
public class MySingleton {
private static instance = new MySingleton ();
private MySingleton (){ }
public MySingleton getInstance {
return instance;
}
}
答案 3 :(得分:1)
你最好使用Holder idiom
inWhichArea = function(map, loc) {
for (var i in feats) {
var area = feats[i].getGeometry();
var poly = new google.maps.Polygon({
paths: area.getAt(0).getArray(),
map: map,
clickable: false
});
if (google.maps.geometry.poly.containsLocation(loc, poly)) {
return feats[i];
}
}
return null;
}
它是懒惰的,因为实例将在第一次调用public class HolderFactory {
public static Singleton get() {
return Holder.instance;
}
private static class Holder {
public static final Singleton instance = new Singleton();
}
}
时创建,并且它是线程安全的,因为类保证由类加载器在单个线程中加载。
您还可以查看此链接,了解有关单身人士和线程安全的更多详细信息:https://shipilev.net/blog/2014/safe-public-construction/