设计模式(三)Singleton Pattern单例设计模式
1.饿汉式
- public class SingletonDemo {
- private static SingletonDemo s=new SingletonDemo();
- private SingletonDemo() {}
- public static SingletonDemo getInstance() {
- return s;
- }
- }
- public class Test {
- public static void main(String[] args) {
- SingletonDemo s=SingletonDemo.getInstance();
- }
- }
步骤: 1.new出静态对象
2.构造方法私有化
3.写一个方法返回静态对象
说明: 1.由于加载类时天然的是线程安全
2.方法没有同步,调用效率高
3.立即加载,没有延时加载的优势
2.懒汉式(延时加载)
- public class SingletonDemo {
- private static SingletonDemo s;
- private SingletonDemo() {}
- public static synchronized SingletonDemo getInstance() {
- if(s==null) s=new SingletonDemo();
- return s;
- }
- }
- public class Test {
- public static void main(String[] args) {
- SingletonDemo s=SingletonDemo.getInstance();
- }
- }
优势: 1.修改点同步,在线程高并发时,能够保证安全性
2.延时new出类,能够做到用的时候去new它
3.双重检测锁实现
由于java编译器优化的原因和JVM底层内部模型的原因,偶尔会出一点问题,不建议使用
这个模式将同步内容下方到if内部,提高了执行效率,不必每次获取对象时都进行同步,至于一次才同步
- public class SingletonDemo {
- private static SingletonDemo instance;
- private SingletonDemo() {}
- public static SingletonDemo getInstance() {
- if(instance==null) {
- SiSingletonDemo sc;
- synchronized (SingletonDemo.class) {
- sc=instance;
- }
- if(sc==null) {
- synchronized (SingletonDemo.class) {
- if(sc==null) {
- sc=new SingletonDemo();
- }
- }
- instance=sc;
- }
- }
- return instance;
- }
- }
4.静态内部类(懒加载)
- public class SingletonDemo {
- private static class SingletonClassInstance{
- private static final SingletonDemo instance=new SingletonDemo();
- }
- private SingletonDemo() {}
- public static SingletonDemo getInstance() {
- return SingletonDemo.getInstance();
- }
- }
5.枚举单例模式
- public enum SingletonDemo {
- INSTANCE; //枚举本来就是单例对象
- //避免了反序列和反射的调用
- //缺点,没有延时调用
- public void singletonOperation() {
- }
- }
6.统一建模语言UML(unified modeling language)
可以拖动类做uml图
利用反射破解单例设计模式(不包含枚举单例,因为枚举型单例是利用JVM底层实现的单例设计模式)
- public class TestSingleObject {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- SingleObject s1=SingleObject.getInstance();
- SingleObject s2=SingleObject.getInstance();
- Class<SingleObject> clazz=(Class<SingleObject>) Class.forName("com.littlepage.singletonPattern.SingleObject");
- Constructor<SingleObject> c=clazz.getDeclaredConstructor(null);
- c.setAccessible(true);//跳过检测
- SingleObject s3=c.newInstance();
- SingleObject s4=c.newInstance();
- System.out.println(s1);
- System.out.println(s2);
- System.out.println(s3);
- System.out.println(s4);
- }
- }
解决方法,在空参构造中加入
if(SingletonObject!=null){
throw new runtimeExpection();
}
进行调用时抛出异常就行
- //举例
- public class SingleObject {
- public static class SingleObjectInstance{
- public static final SingleObject instance=new SingleObject();
- }
- private SingleObject(){
- if(SingleObjectInstance.instance!=null){
- try {
- throw new Exception("运行时异常");
- } catch (Exception e) {
- e.printStackTrace();
- System.exit();
- }
- }
- }
- public static SingleObject getInstance(){
- return SingleObjectInstance.instance;
- }
- }
利用序列化反序列化进行破解
- public class TestSingleObject {
- public static void main(String[] args) throws IOException, ClassNotFoundException {
- SingleObject s1=SingleObject.getInstance();
- System.out.println(s1);
- FileOutputStream fops=new FileOutputStream("d:/a.txt");
- ObjectOutputStream oops=new ObjectOutputStream(fops);
- oops.writeObject(s1);
- oops.close();
- ObjectInputStream ois =new ObjectInputStream(new FileInputStream("d:/a.txt"));
- SingleObject s2=(SingleObject) ois.readObject();
- System.out.println(s2);
- ois.close();
- }
- }
解决办法:
- private Object resdResolve() throws ObjectStreamException{
- return SingleObjectInstance.instance;
- }
添加该代码,可以使读取Object时直接返回已经存在的实例
设计模式(三)Singleton Pattern单例设计模式的更多相关文章
- Java面试 - 什么是单例设计模式,为什么要使用单例设计模式,如何实现单例设计模式(饿汉式和懒汉式)?
什么是单例设计模式? 单例设计模式就是一种控制实例化对象个数的设计模式. 为什么要使用单例设计模式? 使用单例设计模式可以节省内存空间,提高性能.因为很多情况下,有些类是不需要重复产生对象的. 如果重 ...
- 【工作中学习1】两个设计模式:Singleton(单例)和 Adapter(适配器)
好久没有写自己的学习小博客,罪过罪过..最近本菜鸟在项目中接触到经常用到的设计模式,首先是Singleton(单例),这个相信大家都会用到很多,所以自己用代码实现一下,有助于自己学习理解,如有不对,请 ...
- GOF设计模式之1:单例设计模式
1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...
- IOS设计模式第二篇之单例设计模式
现在我们的组件已经有组织了.你需要从其他的地方得到数据,你也可以创建一个API类管理数据这个下个设计模式单例里面介绍. 这个单例设计模式确保这个类仅仅拥有一个实例,并且为这个实例提供一个全局的访问点. ...
- 初学者学Java设计模式(一)------单例设计模式
单例设计模式 单例设计模式是指一个类只会生成一个对象,优点是他可以确保所有对象都访问唯一实例. 具体实现代码如下: public class A { public static void main(S ...
- 【设计模式】Java之单例设计模式
1.单例设计模式:一个类只能有一个对象 1.1 创建单例类的步骤: 1.将构造方法私有化 2.创建私有的静态成员变量 3.共有的静态成员方法,提供当前的唯一对象 1.1 创建单例的两种方式: 1.饿汉 ...
- Java Notes 00 - Singleton Pattern(单例总结)
转:http://hukai.me/java-notes-singleton-pattern/ 这里不赘述单例模式的概念了,直接演示几种不同的实现方式. 0)Eager initialization ...
- 设计模式课程 设计模式精讲 8-10 单例设计模式-ThreadLocal线程单例
1 课程讲解 1.1 应用场景 2 代码演练 2.1 threadLocal应用 1 课程讲解 1.1 应用场景 多线程的时候: 使用同步锁使用时间换空间的方式,(线程排队时间比较长) 而使用thre ...
- 设计模式课程 设计模式精讲 8-8 单例设计模式-Enum枚举单例、原理源码解析以及反编译实战
1 课堂解析 2 代码演练 2.1 枚举类单例解决序列化破坏demo 2.2 枚举类单例解决序列化破坏原理 2.3 枚举类单例解决反射攻击demo 2.4 枚举类单例解决反射攻击原理 3 jad的使用 ...
随机推荐
- The Little Prince-12/11
The Little Prince-12/11 最后一段话!!!hha,傻傻的我们...... 成人们对数字情有独钟.如果你为他们介绍一个朋友,他们从不会问你“他的嗓子怎么样?他爱玩什么游戏?他会采集 ...
- getopt_long_only
st_i2c_parser.c中用到,遂学习一下: 参考:https://blog.csdn.net/pengrui18/article/details/8078813 https://blog.cs ...
- centos系统swap设置 查看swap分区的方法
交换分区swap,意思是“交换”.“实物交易”,它的功能就是在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行,和Windows的虚拟内存(pagefi ...
- python基础:re模块匹配时贪婪和非贪婪模式
python贪婪和非贪婪 正则表达式通常用于在文本中查找匹配的字符串.Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符:非贪婪则相反,总是尝试匹配尽可能少 ...
- pxc集群进入非主模式怎么让最后的节点允许提供服务
这种情况一般是,集群其他节点意外宕机而最后一个节点无法自我仲裁,而进入非主模式. 该模式拒绝任何SQL的执行: ERROR 1047 (08S01): WSREP has not yet prepar ...
- Django Form&ModelForm
ModelForm: 首先导入所需模块 from django.forms import ModelFormfrom django.forms import widgets as form_widge ...
- HTTP小幺鸡接口管理工具安装与配置说明
http://www.xiaoyaoji.cn/doc/TxybXPTdx 小幺鸡接口管理工具安装说明 使用可以参考:https://blog.csdn.net/qincidong/article/d ...
- API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd(转)
前几天拜读了 OpsGenie 公司(一家致力于 Dev & Ops 的公司)的资深工程师 Turgay Çelik 博士写的一篇文章(链接在文末),文中介绍了他们最初也是采用 Nginx 作 ...
- Net SMTP QQ 发送邮件
调用DEMO var currUser = new List<string> { "123@qq.com" , "123@qq.com" , &qu ...
- 【题解】Luogu P2146 [NOI2015]软件包管理器
题面:https://www.luogu.org/problemnew/lists?name=2146 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 这道题就是树链剖分的模板,详细解释见程序. ...