单利模式——java

//饿汉模式
public class Hunger {
	//可能会浪费空间
	private byte[] data1 = new byte[1024*1024];
	private byte[] data2 = new byte[1024*1024];
	private byte[] data3 = new byte[1024*1024];
	private Hunger(){};
	private final static Hunger HUNGER=new Hunger();
	public static Hunger getInstance(){
		return HUNGER;
	}
}
//懒汉模式
public class Lazy {
	/*
	//单线程此处没有问题
	private Lazy() {
		System.out.println(Thread.currentThread().getName()+"ok");
	}
	private static Lazy lazy;
	public Lazy getInstance(){
		if (lazy == null) {
			lazy = new Lazy();
		}
		return lazy;
	}
	*/

	//多线程并发
	private Lazy() {
		System.out.println(Thread.currentThread().getName()+"ok");
	}
	//必须加volatile
	private volatile static Lazy lazy;
	//双层检测锁模式的懒汉模式(DCL懒汉模式)
	public static Lazy getInstance(){
		if (lazy == null) {
			synchronized (Lazy.class) {//这个锁class只能有一个
				if (lazy == null) {
					lazy=new Lazy();//不是一个原则性操作
					/**
					 * 1、分配内存空间
					 * 2、执行构造方法,初始化对象
					 * 3、把这个对象指向这个空间
					 */
				}
			}
		}
		return lazy;
	}
	public static void main(String[] args) {
		for(int i =0;i<=10;i++){
			new Thread(()->{
				Lazy.getInstance();
			}).start();
		}
	}
}

单例模式的双重锁实现:
为什么这里要加volatile关键字呢?我们把lazy=new Lazy()这行代码进行拆分。可以分解为3个步骤:
(1)memory=allocate();// 分配内存
(2)ctorInstanc(memory) //初始化对象
(3)lazy=memory //设置s指向刚分配的地址
如果没有volatile关键字,可能会发生指令重排序。在编译器运行时,从1-2-3 排序为1-3-2。此时两个线程同时进来的时候出现可见性问题,也就是说一个线程执行了1-3,另外一个线程一进来直接返回还未执行2的null对象。而我们的volatile关键之前已经说过了,可以很好地防止指令重排序。也就不会出现这个问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘二壮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值