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;
}
}
设计模式之单例
最新推荐文章于 2024-07-31 10:46:54 发布