设计模式 - 单例模式

一、核心作用

保证一个类只有一个实例,并且提供一个访问该实例的全局访问点(public开发公共方法)。

二、饿汉式实现

类初始化时,立即加载这个对象,也就没有了延时加载;天然的线程安全。

package pattern.singleton;

/**
 * 饿汉式单例模式
 * @author zhou
 *
 */
public class SingletonDemo1 {
	//类初始化时,立即加载这个对象;天然的线程安全
	private static SingletonDemo1 s = new SingletonDemo1(); 
			
	private SingletonDemo1() {}
	
	//方法没有同步,调用效率高
	public static SingletonDemo1 getInstance() {
		return s;
	}
	
}

 

三、懒汉式实现

加synchronized关键字,同步机制,可以避免在并发量高的情况下创建多个对象。

 类初始化时,不初始化这个对象,延时加载;方法同步,调用效率低。

package pattern.singleton;

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

}

 四、静态内部类式

线程安全, 调用效率高,实现了延时加载。

package pattern.singleton;

public class SingletonDemo3 {
	 static class SingletonDemoInstance{
		private static final SingletonDemo3 singleton = new SingletonDemo3();
	}
	
	private SingletonDemo3() {}
	
	public static SingletonDemo3 getInstance() {
		return SingletonDemoInstance.singleton;
	}

}

 

五、枚举式

可以防止反射和反序列化漏洞

package pattern.singleton;

public enum SingletonDemo4 {
	
	//这个枚举元素,本身就是单例;可以避免反射和反序列化的漏洞;没有延时加载
	INSTANCE;

}

六、总结

 

七、

1、通过反射破解跳过单例

package pattern.singleton;

import java.lang.reflect.Constructor;

public class Client {
	public static void main(String[] args)throws Exception {
		SingletonDemo3 singleton = SingletonDemo3.getInstance();
		SingletonDemo3 singleton2 = SingletonDemo3.getInstance();
		System.out.println(singleton == singleton2);
		
		Class<SingletonDemo3> cls = (Class<SingletonDemo3>) Class.forName("pattern.singleton.SingletonDemo3");
		
		Constructor<SingletonDemo3> constructor = cls.getDeclaredConstructor(null);
		constructor.setAccessible(true);
		
		SingletonDemo3 s3 = constructor.newInstance();
		SingletonDemo3 s4 = constructor.newInstance();
		
		System.out.println(s3);
		System.out.println(s4);
		
		/*
		 * System.out.println(s3.getInstance()); System.out.println(s4.getInstance());
		 */
	}

}

 

 2、通过序列化和反序列化破解单例

需要实现 implements Serializable 接口

结果: 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值