两种单例模式

一、懒汉模式

1.1对象在使用时创建

a.保证线程安全

b.优化加锁方式

class Singleton01 {
	private Singleton01() {
	}

	private static Singleton01 instance;

	/**
	 * 线程不安全
	 *  1)存在并发执行的线程 
	 *  2)存在共享数据集
	 *  3)在共享数据集上的操作不是原子操作
	 * 
	 * @return
	 */
	public static Singleton01 getInstance() {
		if (instance == null) {
			instance = new Singleton01();
		}
		return instance;
	}
}

class Singleton02 {
	private Singleton02() {
	}

	private static Singleton02 instance;

	/**
	 * 悲观锁:某一时刻只能有一个线程执行代码内容
	 * 
	 * @return
	 */
	public static synchronized Singleton02 getInstance() {
		if (instance == null) {
			instance = new Singleton02();
		}
		return instance;
	}
}

/*
 * static ReentrantLock lock=new ReentrantLock(false); public static Singleton02
 * getInstance(){ try{ lock.lock(); if(instance==null){ instance=new
 * Singleton02(); } return instance; }finally{ lock.unlock(); } }
 */

class Singleton03 {// 大对象,稀少用
	private Singleton03() {
	}

	/**
	 * volatile 可以保证线程的可见性(当使用此修饰符 修饰一个属性时,只有一个线程改变了此属性的值, 对其它线程立刻可见。),但不能保证原子性。
	 */
	private static volatile Singleton03 instance;

	private static Singleton03 getInstance() {
		// 最坏情况的是所有线程都会进行此代码块
		// 最好情况知有一个线程会 进入如下代码块
		if (instance == null) {
			synchronized (Singleton03.class) {
				if (instance == null) {
					instance = new Singleton03();
				}
				// ...其他操作
			} // synchronized可以保证操作原子性,可见性
		} // 减少阻塞线程的数量(通过双重判定)
		return instance;
	}

	public static void show() {
	};// 其他方法
}

二、饿汉模式

2.1对象在被类加载时创建

a.思考对象大小,

b.小对象可在类加载时创建

c.大对象要延迟加载


//饿汉模式在类加载时才初始化对象
class Singleton04 {
	/** 对象在初始化此属性 */
	private Singleton04() {
	}// 小对象,频繁用

	/**
	 * 类加载时会初始化此属性,而且只初始化1次
	 */
	private static Singleton04 instance = new Singleton04();

	public static Singleton04 getInstance() {
		return instance;
	}

	public static void show() {
	}
}

class Singleton05 {
	private int[] array = new int[2048];

	private Singleton05() {
	}

	// 静态内部类(构建对象,访问类属性,获取方法时,会加载类)
	static class Inner {// 使用内部类延迟对象创建
		private static Singleton05 instance = new Singleton05();
	}

	// 对外的全局访问点(通过此方法获取对象)
	public static Singleton05 getInstance() {
		// 访问内部类的instance属性
		return Inner.instance;
	}

	// 频繁访问show方法时,是不会加载Inner类的
	public static void show() {
		System.out.println("show()");
	}

	public void put(int a) {
		array[0] = a;
	}

}


enum Singleton06 {// Singleton06.class
	instance;// 单例对象(类加载时创建,且只创建一次)
	/*
	 * private Singleton06() {//不能使用public修饰 System.out.println("Singleton06()");
	 * }//默认就有一个私有的构造函数
	 */
	/**
	 * 外界如何访问此方法 Singleton06.instance.show();
	 */
	public void show() {
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值