当前位置: 首页 > news >正文

面向对象设计模式:创建型模式之单例模式

1. 单例模式,Singleton Pattern

1.1 Definition 定义

单例模式是确保类有且仅有一个实例的创建型模式,其提供了获取类唯一实例(全局指针)的方法。
单例模式类提供了一种访问其唯一的对象的方式,可以直接访问,而不需要实例化该类的对象。

1.2 Motivation 动机

Sometimes we want just a single instance of a class to exist in the system. For example, we want just one window manager, or just one factory for a family of products.
有时我们只希望系统中存在一个类的单个实例。例如,我们只需要一个窗口管理器,或者一个产品系列只需要一个工厂。

1.3 Benefit 益处

  • Controlled access to sole instance. 对唯一实例的受控访问
  • More flexible than static class (class with all static properties and methods). 比静态类灵活
    • Static class must be stateless; Singleton could be stateful. 静态类必须无状态,单例可以有状态

1.4 实现

  • 私有构造方法
  • 获取唯一实例引用的静态方法

2. 单例模式类型

2.1 懒汉式-线程不安全

  • 懒加载:是
  • 线程安全:否
public class LazyLoadingSingleton {private static LazyLoadingSingleton lazyLoadingSingleton;private LazyLoadingSingleton() {}public static LazyLoadingSingleton singleton() {if (lazyLoadingSingleton == null) {lazyLoadingSingleton = new LazyLoadingSingleton();}return lazyLoadingSingleton;}public void log(String msg) {System.out.println("Log: " + msg);}
}

2.2 懒汉式-线程安全

  • 懒加载:是
  • 线程安全:是
  • 优点:首次调用初始化,避免内存占用
  • 缺点:影响效率
public class LazyLoadingSingleton {private static LazyLoadingSingleton singleton;private LazyLoadingSingleton() {}public static synchronized LazyLoadingSingleton singleton() {if (singleton == null) {singleton = new LazyLoadingSingleton();}return singleton;}public void log(String msg) {System.out.println("Log: " + msg);}
}

2.3 饿汉式

建议采用

  • 懒加载:否
  • 线程安全:是
  • 优点:未加锁,效率高
  • 缺点:类加载时初始化,浪费内容
public class ClassLoadSingleton {private static ClassLoadSingleton singleton = new ClassLoadSingleton();private ClassLoadSingleton() {}public static ClassLoadSingleton singleton() {return singleton;}public void log(String msg) {System.out.println("Log: " + msg);}
}

解法:静态内部类,延迟类加载的对象实例化

public class ClassLoadSingleton {// private static ClassLoadSingleton singleton = new ClassLoadSingleton();private static class SingleHandler {private static final ClassLoadSingleton singleton = new ClassLoadSingleton();}private ClassLoadSingleton() {}public static ClassLoadSingleton singleton() {return SingleHandler.singleton;}public void log(String msg) {System.out.println("Log: " + msg);}
}

2.4 双重校验锁:校验是否为空

双次校验是否为空,类加锁在双次校验之中
可以使用

  • 懒加载:是
  • 线程安全:是
  • 优点:保证多线程下的效率
package singleton;public class DoubleCheckSingleton {private volatile static DoubleCheckSingleton singleton;private DoubleCheckSingleton() {}public static DoubleCheckSingleton singleton() {if (singleton == null) {synchronized (DoubleCheckSingleton.class) {if (singleton == null) {singleton = new DoubleCheckSingleton();}}}return singleton;}public void log(String msg) {System.out.println("Log: " + msg);}
}

关于 volatile 易失性关键字:
volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值(在某一线程写入寄存器但且未写入变量地址),如果这个变量由别的程序更新了的话,将出现不一致的现象。

http://www.lryc.cn/news/31187.html

相关文章:

  • IsADirectoryError: [Errno 21] Is a directory: ‘.‘
  • 判断三角面片与空间中球体是否相交
  • 继承下的缺省参数值和访问说明符
  • Spring核心模块—— BeanFactoryPostProcessorBeanPostProcessor(后处理器)
  • 产品新人如何培养产品思维?
  • 「兔了个兔」CSS如此之美,看我如何实现可爱兔兔LOADING页面(万字详解附源码)
  • 【Java】阻塞队列 BlcokingQueue 原理、与等待唤醒机制condition/await/singal的关系、多线程安全总结
  • 【水下图像增强】Enhancing Underwater Imagery using Generative Adversarial Networks
  • Maven专题总结—详细版
  • 华为OD机试真题Java实现【字符串加密】真题+解题思路+代码(20222023)
  • 「Python 基础」函数与高阶函数
  • DIV内容滚动,文字符滚动标签marquee兼容稳定不卡
  • SpringBoot_第五章(Web和原理分析)
  • 4-2 Linux进程和内存概念
  • 【微信小程序】计算器案例
  • 408 计算机基础复试笔记 —— 更新中
  • 找出最大数-课后程序(Python程序开发案例教程-黑马程序员编著-第二章-课后作业)
  • Java——N叉树的层序遍历
  • 【Kubernetes】第十八篇 - k8s 服务发现简介
  • Codeforces Round 856 (Div. 2) 最好ak的div2
  • 最新JVM技术: GraalVM,让你一文了解它的方方面面
  • MySQL索引失效的场景
  • Java - 对象的比较
  • [算法]选择排序
  • dp模型——状态机模型C++详解
  • 1.4 条件概率与乘法公式
  • VITA/PYTHON/LUPA families
  • ChatGPT概述:从模型训练到基本应用的介绍
  • C语言实现扫雷【详细讲解+全部源码】
  • Vue2.0开发之——购物车案例-Goods组件封装-商品名称和图片(46)