前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式01——单例模式

设计模式01——单例模式

作者头像
matt
发布2022-10-25 15:51:53
1950
发布2022-10-25 15:51:53
举报
文章被收录于专栏:CSDN迁移CSDN迁移

设计模式01——单例模式

一、分类(Group Of Four/GOF 23)

设计模式一定要运用到具体应用中。 创建型模式:单例模式、工厂模式、抽象工厂模式、创建者模式、原型模式。 结构性模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式。

设计模式的要点: 面向接口设计; 复合 has a,继承 is a; 隔离变化:发现变化部分,把它封装起来。

二、单例模式

  • 作用 保证一个类只有一个对象,并且提供一个访问该实例的全局访问点。
  • 应用场景 任务管理器、配置文件、日志管理、数据库连接池、OS文件系统、Servlet中的Application对象、Spring中的Bean。
  • 优点 内存占用和系统开销小。
  • 实现 主要: (1)饿汉式 构造器私有,类初始化时(天然线程安全过程)就加载这个对象(static)。 线程安全、调用效率高,不能延时加载。
/**
 * 饿汉式单例模式
 */
class SingletonPattern01 {

    // 类加载时对象就创建了
    private static /*final*/ SingletonPattern01 instance = new SingletonPattern01();

    private SingletonPattern01() {
    }

    public static SingletonPattern01 getInstance() {
        return instance;
    }
}

(2)懒汉式 懒加载,需要时才加载,但是需要考虑同步synchronized。 线程安全、资源利用率高,延时加载、并发效率低。

/**
 * 懒汉式单例模式
 */
class SingletonPattern02 {

    private static SingletonPattern02 instance;

    private SingletonPattern02() {
    }

    // 延时加载
    public static synchronized SingletonPattern02 getInstance() {
        if (instance == null) {
            instance = new SingletonPattern02();
        }
        return instance;
    }
}

其他: (3)双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题,不推荐) 同步方法优化为两个同步块,放在if内部。 隐患:实力对象过程可分为1.分配内存空间;2.初始化对象;3.将对象指向刚分配的内存空间。有些编译器为了性能问题可能将2、3步重排序,导致一个线程访问已分配内存空间的对象,还对象没有完成初始化的情况发生。 解决:给对象添加volatile关键词,将对象存放在内存中而非缓存。

/**
 * 双重检测锁式单例模式
 */
class SingletonPattern03 {

    // 添加volatile关键字
    private volatile static SingletonPattern03 instance;

    private SingletonPattern03() {

    }

    public static SingletonPattern03 getInstance(){
        // 提高检测效率
        if (instance == null) {
            synchronized (SingletonPattern03.class) {
                // 可能有多线程同时进入同步块内
                if (instance == null) {
                    instance = new SingletonPattern03();
                }
            }
        }
        return instance;
    }
}

(4)静态内部类式(线程安全、调用效率高,延时加载) 优化注意:线程安全、调用效率高、懒加载 静态内部类的加载不需要依附外部类,在使用时才加载,不过在加载静态内部类的过程中也会加载外部类。

/**
 * 静态内部类式单例模式
 */
class SingletonPattern04 {

    // 静态内部类在使用时加载,天然线程安全
    private static class SingletonPatternClassInstance {
        // 保证只有一个,且只能赋值一次
        private static final SingletonPattern04 instance = new SingletonPattern04();
    }

    public static SingletonPattern04 getInstance() {
        return SingletonPatternClassInstance.instance;
    }

    private SingletonPattern04() {
    }
}

问题:即使构造器私有了,也可以通过反射来调用。

(5)枚举单例(线程安全、调用效率高,不能延时加载) 可以天然防止反射和反序列化,基于JVM底层实现的。4、5较优。

/**
 * 枚举式单例模式
 */
enum SingletonPattern05 {

    // 枚举元素本身就是单例的,INSTANCE就是SingletonPattern05的一个单例
    INSTANCE;

    // 添加需要的操作
    public void singletonPatternOperation() {

    }
}
  • 反射破解 通过c.setAccessible(true);跳过私有构造器保护。
public static void main(String[] args) throw Exception {
	Class<SingletonPattern01> clazz = (Class<SingletonPattern01>) Class.forName("com.ustc.designpattern.SingletonPattern01");
	Constructor<SingletonPattern01> c = clazz.getDeclaredConstructor(null);
	c.setAccessible(true);
	SingletonPattern01 s3 = c.newInstance();
	SingletonPattern01 s4 = c.newInstance();
}

解决:在私有构造器时添加判断,反射操作时抛出异常。

private SingletonPattern01() {
 	if (instance != null) {
        throw new RuntimeException();
    }
}
  • 反序列化破解
public static void main(String[] args) throw Exception {
	FileOutputStream fos = new FileOutputStream("${url}");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(s1);
    oos.close();
    fos.close();

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("${url}"));
    SingletonPattern01 s5 = (SingletonPattern01) ois.readObject();
}

解决:定义readResolve()方法,直接返回此方法中的反序列化对象,而不需要新创建

private Object readResolve() throw ObjectStreamException {
	return instance;
}
  • 性能比较
在这里插入图片描述
在这里插入图片描述

CountDownLatch: 同步辅助类,在完成一组正在其他线程执行的操作之前,它允许一个或多个线程一直等待。 coutDown()当前线程调用此方法,则计数减一,放在finally里执行; await(),调用此方法会一直阻塞当前进程,知道计时器的值为0。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计模式01——单例模式
  • 一、分类(Group Of Four/GOF 23)
  • 二、单例模式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档