设计模式之单例

package singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 单例模式:在系统中只有一个对象
 */

// 饱汉模式 最简单的方式
public class Singleton {
	private static final Singleton singleton = new Singleton();

	private Singleton() {
	}

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

// 饥汉模式 饱汉模式易出现性能问题
class Singleton1 {
	private static Singleton1 single = null;

	private Singleton1() {
	}

	public static Singleton1 getInstance() {
		if (single == null) {
			return new Singleton1();
		}
		return single;
	}
}

// 饥汉模式不能保证在多线程的情况下也能单例
class Singleton2 {
	private static Singleton2 single = null;

	private Singleton2() {
	}

	/**
	 * 首先判断是否为空 如果为空进入同步锁,不为空直接返回原来的对象。 如果同步在方法上,那么调用的时候就会出现锁,浪费资源。
	 */
	public static Singleton2 getInstance() {
		if (single == null) {
			synchronized (Singleton2.class) {
				if (single == null) {
					return new Singleton2();
				}
			}
		}

		return single;
	}
}

/**
 * 线程A开始创建SingletonClass的实例,此时线程B调用了getInstance()方法,
 * 首先判断instance是否为null。按照内存模型,A已经把instance指向了那块内存,
 * 只是还没有调用构造方法,因此B检测到instance不为null,于是直接把instance返回了——问题出现了,
 * 尽管instance不为null,但它并没有构造完成,就像一套房子已经给了你钥匙,但你并不能住进去,因为里面还没有收拾。
 * 此时,如果B在A将instance构造完成之前就是用了这个实例,程序就会出现错误了
 * 
 * 在1.5之之后 提供关键字 volatile关键字保证内存正常
 */

class Singleton3 {
	private volatile static Singleton3 single = null;

	private Singleton3() {
	}

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

		return single;
	}
}

/**
 * 1.5之前怎么办?
 */
class Singleton4 {

	private Singleton4() {
	}

	private static class SingletonClassInstance {
		private static final Singleton4 single = new Singleton4();
	}

	public static Singleton4 getInstance() {
		return SingletonClassInstance.single;
	}
}

/**
 * 以上保证在多线程中是单例,但是如果这个类是可序列化的, 那么该类在反序列化的时候就会创建新的对象,破坏了单例的原则。
 * 可以采用以下方式解决。
 */
class Singleton5 implements Serializable {

	private static final long serialVersionUID = 1L;
	private volatile static Singleton5 single = null;

	private Singleton5() {
	}

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

	// 保证单例在反序列化后的唯一性
	private Object readResolve() throws ObjectStreamException {
		return single;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值