单例模式详解——参考B站课程
课程地址
单例模式是为了确保只有一个实例的存在,从而防止多个实例存在会对程序造成干扰或攻击。
1.懒汉模式
public class LazySingleTon {private static LazySingleTon singleTon;private LazySingleTon(){}public synchronized static LazySingleTon getInstance(){if(singleTon == null)singleTon = new LazySingleTon();return singleTon;}
}
缺点:同步机制导致效率低下,并且无法防控反射攻击,如下
public class LazySingleTon {private static LazySingleTon singleTon;private LazySingleTon(){}public synchronized static LazySingleTon getInstance(){if(singleTon == null)singleTon = new LazySingleTon();else throw new RuntimeException("多个实例不允许");return singleTon;}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Test {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Constructor<LazySingleTon> singleTonConstructor = LazySingleTon.class.getDeclaredConstructor();singleTonConstructor.setAccessible(true);LazySingleTon singleTon = singleTonConstructor.newInstance();LazySingleTon singleTon1 = LazySingleTon.getInstance();System.out.println(singleTon == singleTon1);}
}
2.DCL机制 Double Check Locking
public class DCLSingleTon {private volatile static DCLSingleTon singleTon;private DCLSingleTon(){};public static DCLSingleTon getInstance(){if(singleTon == null){synchronized (DCLSingleTon.class){if(singleTon == null)singleTon = new DCLSingleTon();}}return singleTon;}
}
DCL机制满足一般的并发情况,提高了效率,用volatile修饰singleTon是为了禁止指令重排序和优化,如singleTon = new DCLSingleTon();这一行不是由一步完成的,而是三个步骤完成的,包括堆分配空间、初始化,以及栈内引用指向堆空间地址三个步骤,而voliate保证了指令按照顺序进行,而不会被编译器优化,防止了空指针情况的出现。当然,DCL模式也无法防御反射攻击。
3.饿汉模式
public class SingTon {public static SingTon singTon = new SingTon();private SingTon(){if(singTon != null) throw new RuntimeException("多个实例不允许");}public static SingTon getInstance(){return singTon;}
}
这种模式缺点是单例在最一开始就有了,而不是在需要它的时候才出现。好处是基于JVM类加载机制保证线程安全,并可以防护反射攻击
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Test {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Constructor<SingTon> constructor = SingTon.class.getDeclaredConstructor();constructor.setAccessible(true);SingTon singTon = constructor.newInstance();SingTon singTon1 = SingTon.getInstance();System.out.println(singTon == singTon1);}
}
4.静态内部类
public class InnerSingleTon {public static class InnerClassHoler{private static InnerSingleTon singleTon = new InnerSingleTon();}private InnerSingleTon(){if(InnerClassHoler.singleTon != null) throw new RuntimeException("多个实例不允许");}public static InnerSingleTon getInstance(){return InnerClassHoler.singleTon;}
}
优点可以防护反射攻击、同时只会被加载一次
改进:实现序列化
实现Serializable接口并定义long型序列号,写readResolve()方法
import java.io.Serializable;public class InnerSingleTon implements Serializable {static final long serialVersionUID = 42L;public static class InnerClassHoler{private static InnerSingleTon singleTon = new InnerSingleTon();}private InnerSingleTon(){if(InnerClassHoler.singleTon != null) throw new RuntimeException("多个实例不允许");}public static InnerSingleTon getInstance(){return InnerClassHoler.singleTon;}Object readResolve() {return InnerClassHoler.singleTon;}final int a = 1;}
import java.io.*;public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {InnerSingleTon singTon1 = InnerSingleTon.getInstance();ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("inner"));oos.writeObject(singTon1);oos.close();ObjectInputStream ois = new ObjectInputStream(new FileInputStream("inner"));InnerSingleTon obj = (InnerSingleTon) ois.readObject();System.out.println(singTon1 == obj);}
}
5.枚举
public enum EnumSingleTon {INSTANCE;
}
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {EnumSingleTon singleTon = EnumSingleTon.INSTANCE;EnumSingleTon singleTon1 = EnumSingleTon.INSTANCE;System.out.println(singleTon == singleTon1);Constructor<EnumSingleTon> constructor = EnumSingleTon.class.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);EnumSingleTon singleTon2 = constructor.newInstance("INSTANCE",0);System.out.println(singleTon == singleTon2);}
}
实验结果表明枚举不能通过反射的方式创建实例,枚举类继承抽象类java.lang.Enum,所以在构造器的时候需要传参数
反射安全,反序列化机制安全 线程安全
单例模式详解——参考B站课程相关推荐
- 单例模式应用场景_三、单例模式详解
4.单例模式详解 4.1.课程目标 1.掌握单例模式的应用场景. 2.掌握IDEA环境下的多线程调试方式. 3.掌握保证线程安全的单例模式策略. 4.掌握反射暴力攻击单例解决方案及原理分析. 5.序列 ...
- 以下属于单例模式的优点的是_三、单例模式详解
4.单例模式详解 4.1.课程目标 1.掌握单例模式的应用场景. 2.掌握IDEA环境下的多线程调试方式. 3.掌握保证线程安全的单例模式策略. 4.掌握反射暴力攻击单例解决方案及原理分析. 5.序列 ...
- python单例模式解析_Python下简易的单例模式详解
Python 下的单例模式 要点: 1.某个类只能有一个实例: 2.它必须自行创建这个实例: 3.它必须自行向整个系统提供这个实例 方法:重写new函数 应该考虑的情况: 1.这个单例的类可能继承了别 ...
- java connection 单例_Java设计模式之单例模式详解
Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...
- C++设计模式--单例模式详解(懒汉模式、饿汉模式、双重锁)
C++设计模式--单例模式详解(懒汉模式.饿汉模式.双重锁) 应用场景 一.单例模式是什么? 二.使用步骤 1.UML图 2.代码实现 应用场景 通常我们在做通讯的时候,我们跟服务器数据交互,假如每次 ...
- 跟着别人学设计模式-----(一)单例模式详解
作者:zuoxiaolong8810(左潇龙),转载自:http://www.cnblogs.com/zuoxiaolong/p/pattern2.html 上一章,我们学习了设计模式的概念,以及为什 ...
- java单例设计模式_Java设计模式之单例模式详解
在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...
- ReactiveCocoa详解-李文瀚-专题视频课程
ReactiveCocoa详解-320人已学习 课程介绍 ReactiveCocoa(简称为RAC),RAC具有函数响应式编程特性,由Matt Diephouse开源的一个应用于iOS ...
- Python 单例模式 详解
阅读目录 单例模式 概念 优点 单例模式的实现 使用模块 (常用) 基于 类 实现 基于__new__实现的单例模式(最常用) 基于metaclass(元类)实现的单例模式 metaclass(元类) ...
最新文章
- pandas高级处理-分组与聚合
- Java IO流思维导图
- 如何选择WinPE版本?-日常IT维护必备工具WinPE
- LeetCode MySQL 1264. 页面推荐(union)
- python变量名称的规定_Python 趣闻:如何获得变量的名字?
- 串行测试 并行测试_如何通过CircleCI测试并行性增加构建时间
- chmod 用法示例
- 台州银行笔试考什么_台州银行笔试题型招聘考试真题考什么
- charles Mock测试总结
- Model based RL概述
- 计算机类专业都有什么区别?
- 《指数基金投资指南》银行螺丝钉 ---读书
- vue下利用canvas实现在线图片标注
- Jmeter入门(一)使用Jmeter进行简单的性能测试
- 【笔记】【WPF编程宝典】 第02章 XAML
- 计算机网络终端接口知识,计算机网络实用技术知识点之ISDN接口及配置
- linux gtk 仿qq聊天程序
- Python 三维绘图
- Explain how shipping point is determined?
- 如何学好linux,linux的学习建议