java设计模式-单例模式

  • 2017年7月2日
  • Java

一)饿汉模式(线程安全)

/**
 * 单例模式<br/>
 * 一)饿汉式,线程安全<br/>
 * @author me@longlonggo.com
 * 创建日期:2018年9月16日 <br/>
 */
public class Singleton1 {
	//优点:声明的时候就已经初始化Singleton1,确保了对象的唯一性
	//缺点:声明的时候就初始化对象会浪费不必要的资源
	//如何保证线程安全:类初始化只有一次,所以类创建的对象只会有一个
	private static Singleton1 singletonObj = new Singleton1();
	
	//构造函数要定义为私有的,避免错误执行实例化
	private Singleton1() {}
	
	//返回单例对象
	public Singleton1 getSingleton1() {
		return singletonObj;
	}
}


二)懒汉模式(非线程安全)

/**
 * 单例模式<br/>
 * 二)懒汉式,非线程安全<br/>
 * @author me@longlonggo.com
 * 创建日期:2018年9月16日 <br/>
 */
public class Singleton2 {
	//优点:精确控制单例初始化时间,充分利用延迟加载,只会在调用时才被初始化,
	//缺点:为防止对象被多次加载,使用synchronized进行同步,并发环境可能会降低性能
	private static Singleton2 singletonObj;
	
	//构造函数要定义为私有的,避免错误执行实例化
	private Singleton2() {}
	
	//返回单例对象
	public static synchronized Singleton2 getSingleton2() {
		if(singletonObj == null) {
			singletonObj = new Singleton2();
		}
		return singletonObj;
	}
}

三)内部类实现(线程安全)

/**
 * 单例模式<br/>
 * 三)内部类,线程安全<br/>
 * @author me@longlonggo.com
 * 创建日期:2018年9月16日 <br/>
 */
public class Singleton3 {
	//构造函数要定义为私有的,避免错误执行实例化
	private Singleton3() {}
	
	//优点:
	//1、没有使用并发锁,高并发环境下性能高
	//2、只有getSingleton2()被使用时,实例才会创建(巧妙使用了类和内部类的初始化加载方式)
	//3、内部类被声明为私有的,外部不能访问,只能通过getSingleton2()执行初始化,利用jvm的类初始化机制创建单例
	private static class SingletonHolder{
		private static final Singleton3 singletonObj = new Singleton3();
	}
	
	//返回单例对象
	public static Singleton3 getSingleton2() {
		return SingletonHolder.singletonObj;
	}
}

四)双重检查(线程安全)

/**
 * 单例模式<br/>
 * 四)双重检查,线程安全<br/>
 * @author me@longlonggo.com
 * 创建日期:2018年9月16日 <br/>
 */
public class Singleton4 {
	private static Singleton4 singletonObj;
	
	//构造函数要定义为私有的,避免错误执行实例化
	private Singleton4() {}
	
	//优点:资源利用率高,效率高
	//缺点:第一次加载时比较慢;在JDK1.4之前版本中,java处理器运行乱序执行,所以可能出现失败
	//详参考:https://blog.csdn.net/anjxue/article/details/51038466
	
	//两次判空:
	//1) 第一次判断,提高性能,避免不必要的同步锁操作(synchronized也是消耗性能的)
	//2) 第二次判断,解决多线程下安全问题:
	//	2.1)多个线程同时到达【位置2】
	//	2.2)一线程先执行【位置3】中的代码,并在此时创建单例对象
	//	2.3)一线程执行完后,二线程执行到【位置3】,由于单例对象已经一线程中被创建,所以直接跳出
	public static Singleton4 getSingleton2() {
		if(singletonObj == null) {
			//位置2
			synchronized (Singleton4.class) {
				//位置3
				if(singletonObj == null) {
					singletonObj = new Singleton4();
				}
			}
		}
		return singletonObj;
	}
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注