java中的单例模式.延迟初始化

public static MySingleton getInstance() {
 if (_instance==null) {
   synchronized (MySingleton.class) {
      _instance = new MySingleton();
   }
 }
 return _instance;
} 

1.上述getInstance方法的实现是否存在缺陷?2.这两种实现有什么区别?

1.is there a flaw with the above implementation of the getInstance method? 2.What is the difference between the two implementations.?

public static synchronized MySingleton getInstance() { 
 if (_instance==null) {
  _instance = new MySingleton();
 }

 return _instance;
} 

我在 stackoverflow 中看到了很多关于单例模式的答案,但我发布的问题是主要了解在这种特殊情况下方法和块级别的同步"的区别.

I have seen a lot of answers on the singleton pattern in stackoverflow but the question I have posted is to know mainly difference of 'synchronize' at method and block level in this particular case.

推荐答案

1.上述getInstance的实现是否存在缺陷方法?

1.is there a flaw with the above implementation of the getInstance method?

它不起作用.您最终可以得到多个 Singleton 实例.

It does not work. You can end up with several instances of your Singleton.

2.这两种实现有什么区别?

2.What is the difference between the two implementations.?

第二个有效,但需要同步,当您从不同线程对方法进行大量访问时,这可能会降低系统速度.

The second one works, but requires synchronization, which could slow down the system when you have a lot of accesses to the method from different threads.

最直接正确的实现:

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

更短更好(安全序列化):

Shorter and better (safely serializable):

public enum MySingleton{
    INSTANCE;

    // methods go here
}

单例的延迟初始化是一个引起关注的话题方式与其实际实用性不成比例(IMO争论双重检查锁定的复杂性,您的示例是第一步,只不过是一场小便比赛).

Lazy initialization of singletons is a topic that gets attention way out of proportion with its actual practical usefulness (IMO arguing about the intricacies of double-checked locking, to which your example is the first step, is nothing but a pissing contest).

在 99% 的情况下,您根本不需要延迟初始化,或者第一次引用类时初始化".Java的已经足够好了.在剩下的 1% 的情况下,这是最好的解决方案:

In 99% of all cases, you don't need lazy initialization at all, or the "init when class is first referred" of Java is good enough. In the remaining 1% of cases, this is the best solution:

public enum MySingleton{
    private MySingleton(){}
    private static class Holder {
         static final MySingleton instance = new MySingleton();
    }
    static MySingleton getInstance() { return Holder.instance; }
}

请参阅按需初始化持有人成语

相关文章