线程安全方法

时间:2012-02-17 01:49:32

标签: java multithreading singleton

我目前有一个实现Singleton设计模式的程序:

public class Singleton {
    private static Singleton s;

    private Singleton(){

    }

    public static Singleton getInstance(){
        if(s == null){
            s = new Singleton();
        } 

        return s;
    }
}

在接受采访时我被问到这样的程序,有什么好的选择可以使getInstance方法线程安全。我知道一种方法只是在方法之前标记同步,但是访谈者说还有其他更有效的方法来处理方法线程安全。

任何人都可以提出任何想法吗?

3 个答案:

答案 0 :(得分:1)

至少有三个我能想到的,尽管其中有两个归结为相同的原则。

基本上你可以让classloader担心线程安全,或者从Java5开始使用双重检查锁定。

第一个版本意味着拥有一个包含实际代码的内部类/枚举,第二个版本意味着使Singleton实例变为volatile并使用通常的if-synchronize-if解决方案。

答案 1 :(得分:1)

噢,我的话,不是这个。

写这个的最好方法是最简单的方法:

public class Singleton {
    private static Singleton s = new Singleton();
    // ...
}

使吸气剂同步是第二好的。有一些更复杂的方法可以做到这一点,但没有一个是值得的 - synchronized 非常便宜,并且不要让任何人告诉你。

答案 2 :(得分:1)

1.在类加载时创建实例变量。

优点:

  • 没有同步的线程安全
  • 易于实施

缺点:

  • 尽早创建可能未在应用程序中使用的资源。
  • 客户端应用程序无法传递任何参数,因此我们无法重复使用它。例如,为客户端应用程序提供数据库服务器属性的数据库连接使用通用单例类。

2.同步getInstance()方法

优点:

  • 确保线程安全。
  • 客户端应用程序可以传递参数
  • 实现了懒惰初始化

缺点:

  • 由于锁定开销导致性能下降。
  • 初始化实例变量后不需要的不必要的同步。

3.在if循环和volatile变量

中使用synchronized块

优点:

  • 保证线程安全
  • 客户端应用程序可以传递参数
  • 实现了懒惰初始化
  • 同步开销很小,仅当变量为空时才适用于前几个线程。

缺点:

  • 额外条件