码迷,mamicode.com
首页 > 其他好文 > 详细

单例(Singleton)模式

时间:2015-07-17 15:35:52      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

最简单的单例「饿汉式」?

public class Singleton{

private static Singleton instance=new Singleton();
? ? //other fields
? ? private Singleton(){}
? ? public static Singleton getInstance(){
? ? ? ? ?return instance;
? ? }
? ? //other methods
}

出于性能等方面的考虑,希望延迟实例化单例对象(static 属性在加载类时会被初始化),方案二应运而生,称之为「懒汉式」

public class Singleton {

private static Singleton instance=null;
    // 私有构造方法,防止从外部使用 new 方法创建对象
private Singleton() {
    }
    public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
不幸的是,在高并发的环境中,getInstance()方法返回了多个指向不同的该类实例,也就是说:线程不安全。

线程安全写法A
public class Singleton {

private static Singleton instance=null;
  // 私有构造方法,防止从外部使用 new 方法创建对象
private Singleton() {
  }
  public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
方案A中虽然实现了多线程的安全访问,但在多线程高并发访问情况下,加上 synchronized关键字会使得性能大不如前。

线程安全写法B

public class Singleton {

private static volatile Singleton instance=null;
  // 私有构造方法,防止从外部使用 new 方法创建对象
private Singleton() {
  }
  public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
方案B,我们称之为 Double-Checked Locking (双重检查加锁)模式。在此方案中,还是使用 synchronized,只不过这次只是保证实例化的这段逻辑被一个线程执行。

前述的方法都存在小小的缺陷,有没有一种既能实现延迟加载,又能实现线程安全的方案呢

终极方案

public class Singleton{
     private Singleton(){}

private static class LazyHolder{
private static final Singleton instance = new Singleton();
}

public static Singleton getInstance(){
return LazyHodler.instance;
}
}

单例(Singleton)模式

标签:

原文地址:http://www.cnblogs.com/rgbw/p/4654636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!