单例模式学习

// 从今往后的两个月我会将设计模式学习资料整理成一个系列供我自己和大家参考

单例模式思想

某个类中只能存在一个对象实例,且该类只能提供一个取得该对象实例的方法

饿汉式

1. 静态常量
class Single {
	private Single() {}
	private final static Single instance = new Single();
	public static Single getInstance() {
		return instance;
	}
}

优点:写法简单,在类装载时就完成实例化,没有多线程问题
缺点:若从未使用过这个实例,则会造成内存浪费

2. 静态代码块
class Single {
	private Single() {}
	private final static Single instance;
	static {
		instance = new Single();
	}
	public static Single getInstance() {
		return instance;
	}
}

将实例化放在了静态代码块中,优缺点和静态常量创建的方式一样。

懒汉式

1. 线程不安全
class Single {
	private Single() {}
	private static Single instance;
	public static Single getInstance() {
		if(instance==null) {
			instance = new Single();
		}
		return instance;
	}
}

在实际开发中会有线程安全问题,不能使用

2. 线程安全(同步方法)

将线程不安全的getInstance方法加锁

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

上述方法虽然解决了线程安全问题,但由于每一次获取实例都要进行同步,效率低下,实际开发中不推荐使用
而且由于new Single()会造成指令重排,所以多线程环境下也无法保证单例

3. 线程安全(双重检查)
private static volatile Single instance;
public static Single getInstance() {
	if(instance==null) {
		synchronized(Single.class) {
			if(instance==null) {
				instance = new Single();
			}
		}
	}
	return instance;
}

volatile的作用:

  1. 防止系统对instance进行指令重排,
  2. 通知各个线程instance的变化(可见性),让修改值立即更新到主存
4. 线程安全(静态内部类)

静态内部类只有当被调用其内部的方法时才会被装载,从而实现懒加载

class Single {
	private Single() {}
	private static class SingleInstance {
		private final static Single instance = new Single();
	}
	public static Single getInstance() {
		return SingleInstance.instance;
	}
}
5. 线程安全(枚举)
enum Single {
	INSTANCE;
	public void method() { ... }
}
// 使用
Single instance = Single.INSTANCE;
instance.method();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值