设计模式-----单例模式(全)

目录

 

什么是单例模式

饿汉式

1、静态变量创建

2、静态代码块创建

懒汉式

1、线程不安全的懒汉

2.解决线程安全、但效率低的懒汉式

 3、双重检查:double-check

静态内部类

借用类加载机制

枚举

借用枚举变量使之单例,而枚举构造又可防止反射创建单例


什么是单例模式

  • 单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。

我们可以得到以下信息

  1. 在任何情况下,每个单例类只能有一个实例对象。
  2. 单例类为整个系统提供者唯一的实例。

[比如在计算机系统里可以连接多个打印机,但是只能有一个管理打印机的池子,来避免两个打印作业输入到一个打印机中。]

 

饿汉式

 * 优点:类装载就完成,简单,避免线程同步   * 缺点:没有达到懒加载,若未使用,内存浪费

1、静态变量创建

/**
 * 优点:类装载就完成,简单,避免线程同步
 * 缺点:没有达到懒加载,若未使用,内存浪费
 * @author Lenovo
 *
 */
public class HungrySingleton1 {
	//构造器私有化
	private HungrySingleton1() {
	}
	
	private final static HungrySingleton1 instance = new HungrySingleton1();
	
	public static HungrySingleton1 getInstance() {
		return instance;
	}
	
}

2、静态代码块创建

/**
 * 优点:类装载就完成,简单,避免线程同步
 * 缺点:没有达到懒加载,若未使用,内存浪费
 * @author Lenovo
 *
 */
public class HungrySingleton2 {
	//构造器私有化
	private HungrySingleton2() {
	}
	
	private static HungrySingleton2 instance;
	
	//静态代码块创建
	static {
		instance = new HungrySingleton2();
	}
	
	public static HungrySingleton2 getInstance() {
		return instance;
	}
}

上述代码中的一个缺点是该类加载的时候就会直接new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢 。

懒汉式

1、线程不安全的懒汉

/**
 * 优点:懒加载
 * 缺点:只能在单线程下使用,线程不安全
 * @author Lenovo
 *
 */
public class LazySingleton1 {
	private static LazySingleton1 instance;
	
	private LazySingleton1() {
	}
	
	public static LazySingleton1 getInstance() {
		if (instance== null) {
			instance = new LazySingleton1();
		}
		return instance;
	}
}

2.解决线程安全、但效率低的懒汉式

/**
 * 优点:懒加载,解决了线程不安全的问题
 * 缺点:效率太低了,执行getInstance需要同步,
 * 		其实只需要执行一次实例化就OK,剩下的直接return;
 * @author Lenovo
 *
 */
public class LazySingleton2 {
private static LazySingleton2 instance;
	
	private LazySingleton2() {
	}
	
	//1
	public static synchronized LazySingleton2 getInstance1() {
		if (instance== null) {
			instance = new LazySingleton2();
		}
		return instance;
	}
	
	//2
	//这种方式实际不能起到线程同步的问题
	//若都进入了instance== null,实际还是会产生两个实例
	public static LazySingleton2 getInstance2() {
		if (instance== null) {
			synchronized (instance) {
				instance = new LazySingleton2();
			}
		}
		return instance;
	}
}

 3、双重检查:double-check

/**
 * 双重检查:double-check
 * 优点:懒加载,解决了线程不安全的问题,实例化代码块只执行一次
 * 		线程安全、延迟加载、效率较高
 * @author Lenovo
 *
 */
public class LazySingleton3 {
private static LazySingleton3 instance;
	
	private LazySingleton3() {
	}
	
	public static LazySingleton3 getInstance() {
		if (instance== null) {
			synchronized (instance) {
				if (instance== null) {
					instance = new LazySingleton3();
				}
			}
		}
		return instance;
	}
}

静态内部类

借用类加载机制

/**
 * 优点:使用类装载机制保障安全,类的静态内部类只会在第一次加载时初始化
 *		线程安全(类装载机制保障)、延迟加载、效率高
 * @author Lenovo
 *
 */
public class StaticInnerClassSingleton {
	private StaticInnerClassSingleton() {
	}
	
	//不会在外部类加载时加载,会在被使用时加载
	private static class Innerclass {
		private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
	}
	
	public static StaticInnerClassSingleton getInsatnce() {
		return Innerclass.instance;
	}
	
}

枚举

借用枚举变量使之单例,而枚举构造又可防止反射创建单例

推荐使用


public class EnumSingleton {
	public static void main(String[] args) {
		Singeleton singeleton1 = Singeleton.INSTANCE;
		Singeleton singeleton2 = Singeleton.INSTANCE;
		
		//实际上:Singleton1 == singleton2
		System.out.println(singeleton1 == singeleton2);
		//true
	}
}

/**
 * 优点:避免多线程同步问题,可以防止反序列化重新创建新对象
 * 		推荐使用
 * @author Lenovo
 *
 */
enum Singeleton {
	INSTANCE;//保障单例
	
	public void sayOk() {
		System.out.println("ok!");
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值