常用设计模式——单例模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenbetter1996/article/details/88978119

个人整合学习自

  1. 《Java设计模式》 刘伟 编著

单例模式

Singleton Pattern:确保一个类职业一个实例,并提供一个全局访问点来访问这个唯一实例。也是一直创建型模式。

单例模式的三个要点:

  1. 某个类只能有一个实例;
  2. 它必须自行创建这个实例;
  3. 它必须自行向整个系统提供这个实例。

实现

1. 饿汉式单例

package xyz.cglzwz.designpattern.sp;

/**
 * 饿汉式单例
 * @author chgl16
 * @date 2019-04-02
 */

public class EagerSingleton {
	private static final EagerSingleton instance = new EagerSingleton();
	
	private EagerSingleton() {}
	
	public static EagerSingleton getInstance() {
		return instance;
	}
}

当类加载时,静态变量instance会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。(叫饿汉是eager的意思,渴望第一时间加载)

  • 优点:无需考虑多线程同时访问的问题,可以确保实例的唯一性,而且调用速度和反应时间比以下的懒汉模式要优。
  • 缺点:类加载时就创建,加载时间可能比较长。

2. 懒汉式单例

package xyz.cglzwz.designpattern.sp;

/**
 * 懒汉式单例模式
 * 
 * @author chgl16
 * @date 2019-04-02 
 */

public class LazySingleton {
	private static  LazySingleton instance = null;
	
	private LazySingleton() {}
	
	public static synchronized LazySingleton getInstance() {
		if (instance == null) {
			instance = new LazySingleton();
		}
		
		return instance; 
	}
}

懒汉式都是在第一次调用getInstance()方法时初始化实例,在类加载时并不自行创建,这种技术也称为延迟加载(Lazy Load)技术。

上面代码虽然增加了synchronized修饰符进行线程隐式锁定,解决了线程安全问题。但是多线程高并发访问环境还是会大大降低系统性能。因此可以代码优化下,因为这里可见只需对 instance = new LazySingleton(); 锁定即可。如下改进

public class LazySingleton {
	private static  LazySingleton instance = null;
	
	private LazySingleton() {}
	
	public static LazySingleton getInstance() {
		if (instance == null) {
			synchronized(LazySingleton.class) {
				instance = new LazySingleton();
			}
		}
		
		return instance; 
	}
}

问题貌似解决,但是并非如此。如果多个线程都同时到了 "if (instance == null) "为 true的情况,都通过了判断,由于事先了synchronized加锁机制,只是某一个线程创建了对象。但是后面的线程不知道,会继续创建的(因为已经通过判断了)。

继续改进,使用双重检查锁定

package xyz.cglzwz.designpattern.sp;

/**
 * 懒汉模式双重检查锁定
 * @author chgl16
 * @date 2019-04-03
 */
public class LazySingleton2 {
    // 使用volatile修饰,确保每个线程能够正确处理
	private volatile static LazySingleton2 instance = null;
	
	private LazySingleton2() {}
	
	public static synchronized LazySingleton2 getInstance() {
		// 第一重判断
		if (instance == null) {
			// 锁定代码块
			synchronized (LazySingleton2.class) {
				// 第二重判断
				if (instance == null) {
					// 创建单例实例
					instance = new LazySingleton2();
				}
			}	
		}
		return instance; 
	}
}

猜你喜欢

转载自blog.csdn.net/chenbetter1996/article/details/88978119