java设计模式01-单例模式

单例

含义:确保一个类只有一个实例,并提供该实例的全局访问点。

设计要点:使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现

说明:私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。

Ⅰ懒汉式-线程不安全

/**
 * 懒汉式-线程不安全
 * 如果多个线程能够同时进入 if (instance== null) 
 * 那么会有多个线程执行 instance = new Singleton(); 语句,这将导致实例化多次
 * @author zhongguangneng 799762497@qq.com
 * @Description
 */
public class Singleton_layer {
	private static Singleton_layer instance;
	
	private Singleton_layer(){}
	
	public static Singleton_layer getInstance(){
		if(instance == null ){
			instance = new Singleton_layer();
		}
		return instance;
	}
}

Ⅱ、饿汉式-线程安全

/**
 * 饿汉式-线程安全
 * 缺点:直接实例化的方式也丢失了延迟实例化带来的节约资源的好处。
 * @author zhongguangneng 799762497@qq.com
 * @Description
 */
public class Singleton_layer_safe {
	
	private Singleton_layer_safe(){} 
	private static Singleton_layer_safe instance = new Singleton_layer_safe();

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

Ⅲ、懒汉式-线程安全

/**
 * Ⅲ 懒汉式-线程安全
 *缺点: 当一个线程进入该方法之后,其它试图进入该方法的线程都必须等待,即使 instance 已经被实例化了。
 *这会让线程阻塞时间过长,因此该方法有性能问题,不推荐使用
 * 
 * @author zhongguangneng 799762497@qq.com
 * @Description
 */
public class Singleton_layer_safe1 {
	private static Singleton_layer_safe1 instance;
	private Singleton_layer_safe1(){};
	
	public static synchronized Singleton_layer_safe1 getInstance() {
	    if (instance == null) {
	    	instance = new Singleton_layer_safe1();
	    }
	    return instance;
	}
}

Ⅳ、 双重校验锁-线程安全

/**
 * 只需要被实例化一次,之后就可以直接使用了。
 * 加锁操作只需要对实例化那部分的代码进行,只有当 instance 没有被实例化时,才需要进行加锁。
 * 
 * 只使用了一个 if 语句。在 instance == null 的情况下,如果两个线程都执行了 if 语句,那么两
 * 虽然在 if 语句块内有加锁操作,但是两个线程都会执行 instance= new 
 * Singleton_layer_safe2_doubleCheck (); 这条语句,只是先后的问题,那么就会进行两次实例化。因
 * 此必须使用双重校验锁,也就是需要使用两个 if 语句。
 * volatile 由于 JVM 具有指令重排的特性,使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环 
 * 境下也能正常运行。
 * 
 * @author zhongguangneng 799762497@qq.com
 * @Description
 */
public class Singleton_layer_safe2_doubleCheck {
	private Singleton_layer_safe2_doubleCheck(){};
	private volatile static Singleton_layer_safe2_doubleCheck instance;
	
	public static Singleton_layer_safe2_doubleCheck getInstance(){
		if(instance == null){
			synchronized (Singleton_layer_safe2_doubleCheck.class) {
				if(instance == null){
					instance = new Singleton_layer_safe2_doubleCheck();
				}
			}
			
		}
		return instance;
	}
}

Ⅴ、匿名内部类

/**
 * 匿名内部类实现
 * 
 * JVM加载类的时候并不会加载内部类,只有调用方法的时候才会加载内部类,具有延迟加载的作用,又避免的多线程下多次实例化
 * 
 * @author zhongguangneng 799762497@qq.com
 * @Description
 */
public class Singleton_innerClass {

	private Singleton_innerClass(){}
	
	private  static class SingletonHole{
		private static final Singleton_innerClass instance = new Singleton_innerClass();
	}
	
	public static Singleton_innerClass getInstance(){
		return SingletonHole.instance;
		
	}
}

备注:以上可以看出多线程安全下;最好使用第4,5种方法。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页