fla*_*ash 6 java singleton static synchronization thread-safety
public static MySingleton getInstance() {
if (_instance==null) {
synchronized (MySingleton.class) {
_instance = new MySingleton();
}
}
return _instance;
}
Run Code Online (Sandbox Code Playgroud)
1.上述getInstance方法的实现存在缺陷吗?2.这两种实现有什么区别.
public static synchronized MySingleton getInstance() {
if (_instance==null) {
_instance = new MySingleton();
}
return _instance;
}
Run Code Online (Sandbox Code Playgroud)
我已经在stackoverflow中看到了很多关于单例模式的答案,但我发布的问题是在这种特殊情况下主要知道方法和块级别的'synchronize'的区别.
Mic*_*rdt 27
1.上述getInstance方法的实现存在缺陷吗?
这是行不通的.您最终可能会遇到Singleton的多个实例.
2.这两种实现有什么区别.
第二个工作,但需要同步,当您从不同的线程访问该方法时,这可能会减慢系统速度.
最直接的正确实现:
public class MySingleton{
private static final MySingleton _instance = new MySingleton();
private MySingleton(){}
public static MySingleton getInstance() {
return _instance;
}
}
Run Code Online (Sandbox Code Playgroud)
更短更好(安全可序列化):
public enum MySingleton{
INSTANCE;
// methods go here
}
Run Code Online (Sandbox Code Playgroud)
单身的懒初始化一个话题备受关注的方式与它的实际实用性的比例(IMO争论双重检查锁定的复杂性,对此你的例子是第一步,也不过是撒尿比赛).
在99%的情况下,您根本不需要延迟初始化,或者Java首次引用类时的"初始化"就足够了.在剩下的1%的情况下,这是最好的解决方案:
public enum MySingleton{
private MySingleton(){}
private static class Holder {
static final MySingleton instance = new MySingleton();
}
static MySingleton getInstance() { return Holder.instance; }
}
Run Code Online (Sandbox Code Playgroud)
1.上述getInstance方法的实现存在缺陷吗?
是的,synchronized关键字也应该包装if语句.如果不是那么两个或多个线程可能会通过创建代码.
2.这两种实现有什么区别.
第二个实现是正确的,从我的角度来看更容易理解.
在方法级别使用synchronized为静态方法在类上进行同步,即您在示例中所做的事情1.在方法级别使用synchronized实例方法在对象实例上进行同步.
第一个有两个方面的缺陷。正如其他人在这里提到的,多个线程可以通过
if (_instance==null) {
Run Code Online (Sandbox Code Playgroud)
他们会互相等待,直到对象完全构造好,但他们会进行实例化并替换变量中的引用。
第二个缺陷稍微复杂一些。一个线程可以进入构造函数new MySingleton(),然后 JVM 切换到另一个线程。另一个线程可能会检查变量是否为空,但可能包含对部分构造对象的引用。所以另一个线程在部分构造的单例上工作,这也不好。所以应该避免第一个变体。
第二个变体应该可以正常工作。不要太在意效率,直到您清楚地将其识别为阻滞剂。现代 JVM 可以优化掉不需要的同步,因此在实际生产代码中,这种构造可能永远不会损害性能。
Bob Lee 在Lazy Loading Singletons中讨论了延迟加载单例的各种方法, “正确”的方法是按需初始化(IODH)习惯用法,它需要很少的代码并且具有零同步开销。
static class SingletonHolder {
static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
Run Code Online (Sandbox Code Playgroud)
Bob Lee 还解释了他何时想要延迟加载单例(在测试和开发期间)。老实说,我不相信有很大的好处。
| 归档时间: |
|
| 查看次数: |
6140 次 |
| 最近记录: |