设计模式--单例模式

1 单例模式
当一个类始终只允许创建一个实例,来减少系统的开销,这种类被称为单例类,这种模式被称为单例模式。

public class Singleton {

	private Singleton() {
	}

	private static Singleton instance = new Singleton();

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

测试:

public class SingletonText {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton s1=Singleton.getInstance();
		Singleton s2=Singleton.getInstance();
		System.out.println(s1==s2);
	}
}

会在第一次访问该类的静态变量时初始化单例变量。

//加final关键词 避免子类实现方法破坏单例
public final class LazySingleton implements Serializable {

    private static LazySingleton instance;

    private LazySingleton() {
    };

    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }

    /**
     * 反序列化还用这个对象,避免反序列化破坏单例
     * @return
     */
    public Object readResovle(){
        return instance;
    }
}

系统会在第一次调用getInstance方法时初始化单例,在高并发情况下可能会因为加了同步锁会影响到性能,
第三种模式,创建内部类,从内部类中获取已实例化好的静态变量,这样不会出现线程同步的问题。

public class StaticSingleton {
	
	public static final Integer TEST_NUM=0;

	private StaticSingleton() {
		System.out.println("StaticSingleton->StaticSingleton()");
	}

	public static StaticSingleton getInstance() {
		System.out.println("StaticSingleton->getInstance()");
		return SingletonHolder.instance;
	}

	private static class SingletonHolder {
		private static StaticSingleton instance = new StaticSingleton();
	}
	
	public static void main(String[] args) {
		System.out.println(StaticSingleton.TEST_NUM);
		StaticSingleton singleton=StaticSingleton.getInstance();
	}
}

双从检查–错误的方案

	public static class Singleton {

		private static Singleton singleton;

		private Singleton() {
		}

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

new Singleton();分为两步,第一步分配空间,第二步初始化,出现了重排序,导致其他线程获取到的事一个为初始化的对象。

基于Volatile的解决方案

public class SafeDoubleCheckedLocking {

	private volatile static SafeDoubleCheckedLocking safeDoubleCheckedLocking;
	
	public static SafeDoubleCheckedLocking getInstance(){
		if(safeDoubleCheckedLocking==null){
			synchronized (SafeDoubleCheckedLocking.class) {
				if(safeDoubleCheckedLocking==null){
					safeDoubleCheckedLocking=new SafeDoubleCheckedLocking();
				}
			}
		}
		return safeDoubleCheckedLocking;
	}
}

基于Volatile的解决方案,除了可以对静态字段实现延迟初始化,还可以对实例字段实现延迟初始化。
摘自《Java并发编程的艺术》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值