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

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 classType = LazyType.class;

Constructor 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.(LazyType.java:36)

at instance.lazy.LazyType.getInstance(LazyType.java:50)

at instance.lazy.LazyTypeModifiedReflectAttack.main(LazyTypeModifiedReflectAttack.java:16)

参考内容:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值