Effective Java 学习笔记(三)

本文深入探讨了单例模式的三种实现方式:饿汉式、懒汉式和枚举单例。对比了它们在Lazy初始化、多线程安全性及实现难度上的特点,并分析了各自的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【第3条:用私有够在其或者枚举类型强化Singleton属性】

其实《effective java》这一节讲其实就是单例模式。书中的例子提到饿汉式和枚举单例。

那么就出现三种单例模式:饿汉式、懒汉式、枚举。

关于单例模式的应用场景可以看下这篇文章:http://blog.youkuaiyun.com/tanyujing/article/details/14160941

饿汉式

是否 Lazy 初始化:

是否多线程安全:

实现难度:

描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloder 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。

public class Util {
	
	private static Util util = new Util();
	
	/**
	 * 饿汉式写法,一般情况下使用
	 * @return
	 */
	public static Util GetInstance(){
		return util;
	}
	
	
	/**
	 * 判断是否手机电话号码
	 * @param str
	 * @return
	 */
	public boolean  IsMobilePhoneNum(String str){
		Pattern pattern = Pattern.compile("^(1)\\d{10}$");
		Matcher matcher=null;
		if (str!=null&&!str.isEmpty()) {
			 matcher = pattern.matcher(str);
		}
		return matcher.find();
	} 
	
}
懒汉式

是否 Lazy 初始化:

是否多线程安全:

实现难度:

描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。

public class Util {

	private static Util util;

	/**
	 * 懒汉式写法,synchronized修饰保证线程同步
	 * 
	 * @return
	 */
	public static synchronized Util GetInstance() {
		if (util == null) {
			util = new Util();
		}
		return util;
	}

	/**
	 * 判断是否手机电话号码
	 * 
	 * @param str
	 * @return
	 */
	public boolean IsMobilePhoneNum(String str) {
		Pattern pattern = Pattern.compile("^(1)\\d{10}$");
		Matcher matcher = null;
		if (str != null && !str.isEmpty()) {
			matcher = pattern.matcher(str);
		}
		return matcher.find();
	}

}
枚举单例

JDK 版本:JDK1.5 起

是否 Lazy 初始化:

是否多线程安全:

实现难度:

描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

public enum Elvis{
		instance;
		private int i=0;
		public void doSomeThing(){
			i++;
			System.out.println(i);
			System.out.println("doSomeThing");
		}
	}
使用示例

for (int i = 0; i < 10; i++) {
			Elvis.instance.doSomeThing();
		}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值