看的视频:https://www.bilibili.com/video/av43896218/?p=286

实现方式:(构造器私有,提供一个外部可以访问的方法(可以提供实例)

1、饿汉式:线程安全,调用效率高, 不能延时加载

2、懒汉式:线程安全,调用效率不高,可以延时加载(要用的时候才加载  )

3、双重锁检测式:“由于JVM底层内部模型原因,偶尔会出现问题,不建议使用”

4、静态内部类式:线程安全,调用效率高,且可以实现延时加载

(上面的四种方式都可以通过反射和反序列化 破坏 单例模式)

5、枚举:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化

如果单例对象占用资源少,不需要延时加载:

枚举式 优于 饿汉式

如果单例对象占用资源大, 需要延时加载:

静态内部类式 优于 懒汉式

饿汉式:

/*
饿汉式: 最开始就已经把实例给创建好了
*/
public class Singleton01 {
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
private Singleton01(){
}
public static Singleton01 getInstance(){
return instance;
}
}

懒汉式:

/*
懒汉式: 用的时候才会初始化实例 效率不高就是因为有synchronized这个关键字
*/
public class Singleton02 {
private static Singleton02 instance = null;
private Singleton02(){
}
public static synchronized Singleton02 getInstance(){
if(instance == null){
instance = new Singleton02();
}
return instance;
}
}

静态内部类:

/*
静态内部类: 只有在主动调用这个类的时候才会加载 外部类加载的时候 静态内部类不会加载
*/
public class Singleton03 {
static class Inner{
private static Singleton03 instance = new Singleton03();
}
private Singleton03(){ }
public static Singleton03 getInstance(){
return Inner.instance;
}
}

枚举:

/*
枚举 天然的可以防止 反射和反序列化
*/
public enum Singleton04 {
INSTANCE; //就表示一个实例 获取的时候直接 Singleton04.INSTANCE
public void method(){
//这里可以写一些方法
}
}

通过反射破坏单例模式:

public class Test01 {
public static void main(String[] args) throws Exception{
Class<?> clazz = Class.forName("com.test.Singleton01");
//获取构造函数:
Constructor c = clazz.getDeclaredConstructor();
c.setAccessible(true); //对于私有属性和方法 设置为允许访问
//通过构造函数 构造实例
Singleton01 singleton001 = (Singleton01)c.newInstance();
Singleton01 singleton002 = (Singleton01)c.newInstance();
System.out.println(singleton001 == singleton002); // false
}
}

如何破坏反射:

public class Singleton01 {
private static boolean flag = false; //标志位
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
// 上面的已经调用过一次 这个私有的构造函数了

private Singleton01(){ //反射的时候操作的就是这个私有的构造函数
synchronized (Singleton01.class){
if(flag == false){
flag = true;
}else{ //表示第二次用构造函数进行实例化
throw new RuntimeException("单例模式正在被破坏");
}
}
}
public Singleton01 getInstance(){
return instance;
}
}

在用反射就会报错....

通过反序列化破坏单例模式:

对象序列化:将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或者通过网络发送到任何其他程序中。

反序列化:将字节流转化为对象的过程。

public class Test01 {
public static void main(String[] args) throws Exception{

//序列化 singleton001 Singleton01要实现 Serializable
Singleton01 singleton001 = Singleton01.getInstance();
Singleton01 singleton002 = Singleton01.getInstance();
FileOutputStream fos = new FileOutputStream("d:/a.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(singleton001);
oos.close();
fos.close(); //反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/a.txt"));
Singleton01 singleton003 = (Singleton01)ois.readObject(); System.out.println(singleton001 == singleton002); //true
System.out.println(singleton001 == singleton003); //false
}
}

防止反序列化:

public class Singleton01 implements Serializable {
public static Singleton01 instance = new Singleton01(); //一开始就已经创建好了
private Singleton01(){
}
public static Singleton01 getInstance(){
return instance;
}
//在反序列化的时候 直接调用这个方法 返回instance 而不是返回反序列化后的新对象
private Object readResolve() throws ObjectStreamException {
return instance;
}
}

创建者模式 -- 单例模式(反射&序列化)的更多相关文章

  1. effective java笔记之单例模式与序列化

    单例模式:"一个类有且仅有一个实例,并且自行实例化向整个系统提供." 单例模式实现方式有多种,例如懒汉模式(等用到时候再实例化),饿汉模式(类加载时就实例化)等,这里用饿汉模式方法 ...

  2. (Builder)创建者模式

    定义: 建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示. 适用性: 当流程算法可以固定几个步骤,步骤的算法步骤执行顺序固定,且制造的产品可以唯一确定,这时使用创建 ...

  3. [设计模式] 3 创建者模式 builder

    转载http://blog.csdn.net/wuzhekai1985/article/details/6667467 建造者模式的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不 ...

  4. Builder创建者模式

    http://www.codeproject.com/Articles/42415/Builder-Design-Pattern In Elizabeth's day care center, the ...

  5. OOAD(面向对象分析和设计)GRASP之创建者模式(Creator)又称生成器模式学习笔记

    说OOAD是一门玄学,一点都不为过.又或许是因为我之前一直没有很好的建立面向对象的思想,更有可能是因为练得不够多...总之,一直没能很好理解,哪怕把一本叫做<UML和模式应用>的书翻来覆去 ...

  6. C#设计模式之五创建者模式(Builder)【创建型】

    一.引言  今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一个复杂的物品,它主要是由CPU.主板.硬 ...

  7. 创建者模式Builder

    创建者模式: 分离对象子组件的单独构造(由Builder来负责)和装配(由Director负责),对象的构造比较复杂时使用 该模式. 类图: Builder 抽象建造者接口,规范各个组成部分的构建. ...

  8. 设计模式学习总结(五)创建者模式(Builder)

    创建者模式,主要针对某些产品有类似的生产步骤,且有需要有先后顺序的进行各个部件的生成. 一.示例展示: 通过学习及总结,以下是我完成的创建者模式的示例: 1.创建产品类:Laptop public c ...

  9. 复杂UI的组织-创建者模式-uitableview思想

    复杂节目的组织-创建者模式-uitableview思想 整体说明,部件规格说明

随机推荐

  1. linux 修改IP, DNS -(转自fighter)

    linux下修改IP.DNS.路由命令行设置 ubuntu 版本命令行设置IP cat /etc/network/interfaces # This file describes the networ ...

  2. 【Web前端HTML5&CSS3】12-字体

    笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版 目录 字体 1. 字体相关的样式 2. font-family 3. 几种字体 手写体 艺术体 乱码字体 中文字体 4 ...

  3. 五:.net core(.NET 6)使用Autofac实现依赖注入

    Autofac的简单使用: 由于将来可能引用很多包,为了保持统一队形,我们再新建一个类库项目Wsk.Core.Package,当做包的引用集合: 删掉Class1,把Wsk.Core.Wsk.Core ...

  4. opencv——自适应阈值Canny边缘检测

    前言 Canny边缘检测速度很快,OpenCV中经常会用到Canny边缘检测,以前的Demo中使用Canny边缘检测都是自己手动修改高低阈值参数,最近正好要研究点小东西时,就想能不能做个自适应的阈值, ...

  5. SpringBoot 实现整合log4j2日志

    关于日志级别 共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF. ...

  6. .Net RabbitMQ实战指南——客户端开发

    开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...

  7. Python脚本语言写法

    Python脚本语言写法 脚本语言的开始行,是指文件中的代码用什么可执行程序去运行它,就这么简单. #!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的pyth ...

  8. Hash源码注释解析

    部分代码注释解析: 1 import java.io.IOException; 2 import java.io.InvalidObjectException; 3 import java.io.Se ...

  9. 从简单示例看对象的创建过程, 为什么双重检查的单例模式,分析Volatile关键字不能少

    编译指令 :javac Test.java 反编译指令: javap -v Test 代码 public class ObjectTest { int m = 8; public static voi ...

  10. fail2ban防护ssh免于暴力破解

    一.背景 开放到公网的主机无时无刻不在遭受攻击,其中ssh暴力破解频率最高,会有无数机器不分日夜地搜索公网上的猎物,然后进行弱密码尝试 如果你的公网机器恰巧设的弱密码,估计刚装上系统,没过几小时别人就 ...