JAVA三种实现单例模式方法(一):懒汉式实现单例设计模式

原创 2018年04月17日 18:40:26
package instance.lazy;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 懒汉式单例
 * @author jingzi
 * 单例模式是最常用的设计模式,一个完美的单例需要做到哪些事呢?
 * 1、单例
 * 2、延迟加载
 * 3、线程安全
 * 4、没有性能问题
 * 5、防止序列化产生新对象
 * 6、防止反射攻击
 */
public class LazyType implements Serializable {
	
	private static final long serialVersionUID = 6427931149119200875L;
	/**
	 * 声明为volatile,保证多线程可见性、防止“instance = new LazyType()”指令重排序。
	 * 注:instance = new LazyType()是非原子性操作。
	 * instance = null:延迟加载。
	 */
	private volatile static LazyType instance = null;  
	
	private static boolean flag = false;
	
	private LazyType() {
		//防止反射攻击
		synchronized (LazyType.class) {
			if (false == flag) {
				flag = !flag;
			} else {
				//被反射攻击,抛出异常。
				throw new RuntimeException("Reflected attack!");
			}
		}
	}
	/**
	 * 执行两次校验:很有必要,这样可以保证线程安全。
	 * 当多线程调用时,如果多个线程同时执行完了第一次检查,其中一个进入他不代码块创建了实例,
	 * 后面的线程因第二次检查不会创建实例。
	 * @return
	 */
	public static LazyType getInstance() {
		if (null == instance) {//第一次检查
			synchronized (LazyType.class) {
				if (null == instance) {//第二次检查
					instance = new LazyType();
				}
			}
		}
		return instance;
	}
	
	/**
	 * 如果实现了Serializable, 必须重写这个方法,才能保证其反序列化依旧是单例,即防止序列化产生新对象。
	 * @return
	 * @throws ObjectStreamException
	 */
	private Object readResolve() throws ObjectStreamException {
		return instance;
	}
	
	/**
	 * 所执行的业务功能
	 */
	public void doSomethingElse() {
		
	}
}

测试,防止单例模式被java反射攻击:

package instance.lazy;
import java.lang.reflect.Constructor;
public class LazyTypeModifiedReflectAttack {
	public static void main(String[] args){
		try {
			Class<LazyType> classType = LazyType.class;
			Constructor<LazyType> c = classType.getDeclaredConstructor(null);
			c.setAccessible(true);
			LazyType e1 = (LazyType)c.newInstance();
			System.out.println("e1.hashCode():" + e1.hashCode());
			LazyType e2 = LazyType.getInstance();
			System.out.println("e2.hashCode():" + e2.hashCode());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

测试结果:

e1.hashCode():118352462
java.lang.RuntimeException: Reflected attack!
	at instance.lazy.LazyType.<init>(LazyType.java:36)
	at instance.lazy.LazyType.getInstance(LazyType.java:50)
	at instance.lazy.LazyTypeModifiedReflectAttack.main(LazyTypeModifiedReflectAttack.java:16)

这么写的具体原因可见:https://www.zhihu.com/question/29971746

此外,如何防止单例模式被JAVA反射攻击: https://blog.csdn.net/u013256816/article/details/50525335

参考内容:

https://blog.csdn.net/wzgiceman/article/details/51809985

https://blog.csdn.net/huangyuan_xuan/article/details/52193006

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

Dll中导出类--Delphi实战之一

   Dll中导出类--Delphi实战之一作者: Musicwind®创建时间: 2001-11-01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...
  • Musicwind
  • Musicwind
  • 2001-11-02 21:24:00
  • 1645

设计模式-单例模式(饿汉式及懒汉式的Java实现)

单例模式单例模式在程序设计中使用的频率非常之高,其设计的目的是为了在程序中提供唯一一个对象(保证只被构造一次),例如写入日志的log对象,windows的任务管理器实现(只能打开一个)。这里主要介绍单...
  • zjx409
  • zjx409
  • 2015-08-03 22:57:41
  • 5683

设计模式之单例模式-饿汉式&懒汉式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。” 通过单例模式可以保证系统中一个类只有一个实例而且该...
  • inslow
  • inslow
  • 2017-01-08 18:24:52
  • 512

单例设计模式之饿汉式和懒汉式

1.设计模式? 设计模式是在大量的实践中总结和理论化之后优选的代码结构,编程风格,以及解决问题的思考方式。 2.单例模式的概念?     单例模式,我们首先必须将类在一个虚拟机中只能产生一个对象...
  • weixin_39039345
  • weixin_39039345
  • 2017-11-23 18:37:43
  • 94

Java设计模式之单例模式(恶汉式和懒汉式)

/*  * 单例模式:  *         饿汉式:类一加载就创建对象  *         懒汉式:用的时候,才去创建对象  * 面试题:单例模式的思想是什么?写一个代码体现(我们最好写懒...
  • u012110719
  • u012110719
  • 2015-05-02 08:47:38
  • 4023

单例模式三种实现----饿汉式 饱汉式(懒汉式) 双重锁模式--------(java复习)

在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。 一、什么时候使用单例模式: 当实例存...
  • qq_27093465
  • qq_27093465
  • 2016-03-25 13:56:01
  • 4788

设计模式——单例模式的几种实现方式

1.饿汉式:静态常量 这种方法非常的简单,因为单例的实例被声明成static和final变量了,在第一次加载类到内存中时就会初始化,所以会创建实例本身是线程安全的。public class Singl...
  • bingogirl
  • bingogirl
  • 2016-09-01 00:03:25
  • 2088

单例模式---懒汉与饿汉模式和静态内部类实现

单例模式是最基本的 java 设计模式之一 主要有两种设计方法,主要分为饿汉式与懒汉式饿汉式比较简单,直接使用常量即可,主要代码如下: private static final SingleM...
  • jslcylcy
  • jslcylcy
  • 2017-05-25 11:44:26
  • 642

Java单例模式--饿汉式、懒汉式需要怎么写

Java 单例模式 饿汉 懒汉 spring IOC中使用懒汉式、饿汉式
  • u013905744
  • u013905744
  • 2016-10-07 14:23:31
  • 4025

java面试题:java中的单例设计模式及两种实现方法的代码举例

java面试时经常会问到关于单例设计模式,因为它能考察的知识点较多且在开发中经常用到。 那我就来说一说我对于单例设计模式的一些浅见。 首先,在Java中,什么是单例呢? 就是保证类在内存中只有一...
  • qq_24693837
  • qq_24693837
  • 2016-11-23 20:49:03
  • 1251
收藏助手
不良信息举报
您举报文章:JAVA三种实现单例模式方法(一):懒汉式实现单例设计模式
举报原因:
原因补充:

(最多只允许输入30个字)