偷颗菜抱回家的gravatar头像
偷颗菜抱回家 2016-12-16 10:31:43

java实现两种常用的线程安全的单例模式

单例模式经常会使用,但是在多线程环境下,不规范的单例写法还是会出现单例对象并非单例。这里分享两个常用的线程安全的单例模式,当然还有其他实现线程安全的单例。

1、双层检测

public class Instance implements Serializable {
	/** 
	 * @since JDK 1.7 
	 */ 
	private static final long serialVersionUID = -4827759752671402638L;
	private volatile static Instance instance = null;
	private Instance(){}
	//双层检测,在1.5以后Instance对象开始提供volatile关键字修饰变量来达到稳定效果
	public static Instance getInstance(){
		if(instance == null){
			//注意是synchronized 字节码,不是synchronized 对象
			synchronized(Instance.class){
				if(instance == null){
					instance = new Instance();
				}
			}
		}
		return instance;
	}
	
	@Override
	public String toString() {
		return "DCL检测";
	}
	
	/**
    * 因实现Serializable接口。反序列化单例需要 ,在反序列化时会被调用,若不加此方法 则反序列化的类不是单例的
    */
	private Object readResolve() throws ObjectStreamException {
		return getInstance();
    }
	
}

 

2、静态内部类

public class Instance2 implements Serializable {
	/** 
	 * @since JDK 1.7 
	 */ 
	private static final long serialVersionUID = 6921443757360064842L;

	private Instance2(){}
	//静态内部类
	private static class Instance2Holder{
		private static Instance2 instance = new Instance2();
	}
	
	public static Instance2 getInstance(){
		return Instance2Holder.instance;
	}
	
	@Override
	public String toString() {
		return "静态内部类";
	}
	
	/**
    * 因实现Serializable接口。反序列化单例需要 ,在反序列化时会被调用,若不加此方法 则反序列化的类不是单例的
    */
	private Object readResolve() throws ObjectStreamException {
		return getInstance();
    }
}

 

运行截图:

java实现两种常用的线程安全的单例模式

java实现两种常用的线程安全的单例模式


打赏

顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友