Java 之 设计模式

1.单例模式

1. ​​饿汉式(Eager Initialization)​
  • ​核心原理​​:类加载时立即创建实例,通过静态变量直接初始化。

  • ​代码示例​​:

public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {} // 私有构造public static Singleton getInstance() {return INSTANCE;}
}
  • ​特点​​:

    • ✅ ​​线程安全​​:JVM 类加载机制保证唯一实例。

    • ❌ ​​非延迟加载​​:实例在类加载时创建,若未被使用则浪费资源。

  • ​适用场景​​:实例小、启动时即需使用的场景(如配置管理器)

2. ​​懒汉式(Lazy Initialization)​
(1) 基础版(线程不安全)
  • ​代码示例​​:

  • public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton(); // 多线程下可能重复创建}return instance;}
    }

    ​问题​​:多线程并发时可能创建多个实例

3. ​​双重检查锁(Double-Checked Locking, DCL)​

     volatile在DCL中的两个核心作用:禁止指令重排序和保证内存可见性​

  • ​核心优化​​:减少同步次数,兼顾性能与线程安全。

  • ​代码示例​​:

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

关键点​​:

  • ✅ ​​延迟加载​​:实例在首次调用时创建。

  • ✅ ​​高效同步​​:仅首次创建时加锁。

  • ⚠️ ​​需 volatile​​:防止指令重排序导致未初始化对象被使用(JDK 1.5+ 生效)

4. ​​静态内部类(Static Inner Class)​
  • ​原理​​:利用 JVM 类加载机制,内部类首次调用时才加载并初始化实例。

  • ​代码示例​​:

public class Singleton {private Singleton() {}private static class Holder {static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
}
  • 点​​:

    • ✅ ​​线程安全​​:类加载过程由 JVM 保证同步。

    • ✅ ​​延迟加载​​:无额外同步开销。

  • ​局限​​:无法通过参数初始化实例

2.生产者-消费者模式

生产者-消费者模式是一种经典的并发设计模式,用于解决生产者和消费者线程之间的资源协作问题。其核心是​​通过共享缓冲区(BlockingQueue)解耦生产与消费逻辑​​,平衡两者的处理速度差异。以下是该模式的实现方式、关键要点及最佳实践

1.核心实现方式​

1. ​​基础版:wait()/notifyAll()

通过 synchronized块和 wait()/notifyAll()手动控制线程协作

public class Buffer {private Queue<Integer> queue = new LinkedList<>();private int capacity = 10;public synchronized void produce(int value) throws InterruptedException {while (queue.size() == capacity) { // 缓冲区满时等待wait();}queue.offer(value);notifyAll(); // 唤醒所有等待线程}public synchronized int consume() throws InterruptedException {while (queue.isEmpty()) { // 缓冲区空时等待wait();}int value = queue.poll();notifyAll(); // 唤醒生产者return value;}
}
2.核心组件与原理​
  1. ​生产者​

    • 负责生成数据(如网络请求结果、传感器数据)并存入缓冲区。

    • 当缓冲区满时,生产者线程自动阻塞(避免资源浪费)。

  2. ​消费者​

    • 从缓冲区取出数据并处理(如更新 UI、保存到数据库)。

    • 当缓冲区空时,消费者线程自动阻塞(避免空转)。

  3. ​缓冲区​

    • 作为数据中转站,通常用​​线程安全队列​​实现(如 BlockingQueue)。

    • 特性:容量限制、线程安全的存取操作(put()/take())。

  4. ​同步机制​

    • 确保生产者和消费者不会同时操作缓冲区导致数据竞争(如队列空/满时的阻塞唤醒)

3.Android 典型应用场景​
  1. ​异步任务管理​

    • 生产者:后台线程下载图片 → 消费者:主线程更新 UI。

    • 示例:HandlerThreadHandler实现任务队列(生产者投递任务,Looper消费任务)。

  2. ​数据流处理​

    • 生产者:摄像头采集帧 → 消费者:子线程进行图像识别。

  3. ​高并发请求控制​

    • 限制同时处理的网络请求数量(如线程池任务队列。

  4. ​跨进程通信​

    • 通过 IntentService或 WorkManager实现后台任务生产与消费

3.工厂模式

1. ​​简单工厂模式(静态工厂)​
  • ​核心​​:一个工厂类根据参数创建不同对象。

  • ​Android应用​​:

    • BitmapFactory:通过decodeResource()decodeFile()等方法,根据资源类型自动创建Bitmap,隐藏JPEG/PNG等格式的解码细节。

    • ​通知创建​​:统一工厂根据类型生成不同样式通知(如基础通知、大图通知)。


 2. ​​工厂方法模式(子类决策)​
  • ​核心​​:定义抽象工厂接口,由子类实现具体对象创建。

  • ​Android应用​​:

    • LayoutInflater

      • 系统通过onCreateView()抽象方法,让子类决定如何创建View。

      • ​自定义场景​​:通过setFactory2()替换系统控件(如全局将TextView替换为AppCompatTextView),实现兼容性适配。

    • ​RecyclerView​​:onCreateViewHolder()由子类决定创建哪种ViewHolder,解耦视图类型与适配器逻辑。


 3. ​​抽象工厂模式(产品家族)​
  • ​核心​​:创建一组相关对象(如整套UI组件)。

  • ​Android应用​​:

    • Resources体系:根据设备配置(分辨率、语言)自动加载匹配的Drawable、字符串等资源,不同ResourcesImpl生产当前环境所需的资源家族。

    • ​主题切换​​:为深色/浅色模式提供配套的按钮、文本框等UI组件。


  4. ​​开源框架中的应用​
  • ​Retrofit​​:Converter.Factory根据接口返回类型选择数据解析器(如GsonConverterFactory)。

  • ​Glide​​:ModelLoaderFactory根据数据类型(URL、File等)创建对应的资源加载器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92409.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[激光原理与应用-185]:光学器件 - BBO、LBO、CLBO晶体的全面比较

一、相同点非线性光学晶体属性BBO、LBO、CLBO均为非中心对称晶体&#xff0c;具备非线性光学效应&#xff0c;广泛应用于激光频率转换&#xff08;如倍频、三倍频、和频、差频&#xff09;、光学参量振荡&#xff08;OPO&#xff09;及电光调制等领域。宽透光范围三者均覆盖紫外…

Android APN加载耗时优化可行性分析

背景 根据Android系统底层机制和行业实践,本文讨论 APN 加载耗时从4.2s降至0.8s的数据合理性和技术可行性,需结合具体优化手段和硬件环境综合分析。 以下是关键判断依据及行业参考: ⚙️ 一、APN加载耗时基准参考 未优化场景的典型耗时 首次开机或重置后:APN需从apns-con…

mysql进阶-sql调优

概述优化索引在MySQL初阶的课程中已经介绍了索引&#xff0c;我们知道InnoDB存储引擎使⽤B树作为索引默认的数据结构来组织数据&#xff0c;为频繁查询的列建⽴索引可以有效的提升查询效率&#xff0c;那么如何利⽤索引编写出⾼效的SQL查询语句&#xff1f;以及如何分析某个查询…

海量数据处理问题详解

1.从a&#xff0c;b两个文件各存放50亿个url&#xff08;每个url大小为64B&#xff09;&#xff0c;如何在内存为4G中查找a&#xff0c;b中相同的url 计算各文件存放大小&#xff1a;50亿*64B 大约为320G&#xff0c;而内存只有4G&#xff0c;显然存放不下&#xff0c;此时我们…

AI 记忆管理系统:工程实现设计方案

本文档为《从“健忘”到“懂我”&#xff1a;构建新一代AI记忆系统》中所述理念的详细工程实现方案。它将聚焦于技术选型、模块设计、数据流转和核心算法&#xff0c;为开发团队提供清晰的落地指引。 1. 系统架构与技术选型 为实现分层记忆与读写分离的设计理念&#xff0c;我们…

Linux驱动学习day26天(RS485)

一、原理通过芯片将232信号转换成485信号&#xff0c;485表示0和1的方法&#xff1a;Va - Vb 的电压差在2~6V时表示1&#xff0c;Va - Vb 的电压差在-2~-6V时表示0。这样传输不容易受到干扰&#xff0c;并且传输距离长。我们需要做的事情就是发送&#xff1a;使能DE(driver ena…

从零构建TransformerP1-了解设计

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录引言1 概念回顾1.1 序列任务1.1.1 将序列变成模型…

JVM 终止机制详解:用户线程与守护线程

用户线程未执行完是否会阻止 JVM 终止&#xff1f;答案是&#xff1a;取决于线程类型。让我详细解释&#xff1a; 核心规则 #mermaid-svg-bg5xpyMAeRWNGGk2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bg5xpyMAe…

Linux Vim 常用快捷键

Vim中最常用的快捷键&#xff0c;熟练掌握它们可以大大提高编辑效率。移动光标h- 左移j- 下移k- 上移l- 右移w- 移动到下一个单词开头b- 移动到上一个单词开头e- 移动到单词末尾0- 移动到行首$- 移动到行尾gg- 移动到文件开头G- 移动到文件末尾:n- 跳转到第n行插入模式i- 在光标…

【Bellman负环】Cycle Finding

题目翻译给定一个有向图&#xff0c;你的任务是判断它是否包含负环&#xff0c;并给出这样一个环的示例。输入 第一行输入两个整数 n 和 m&#xff1a;分别表示节点数和边数。节点编号为 1, 2, ..., n。 接下来 m 行描述边&#xff0c;每行有三个整数 a, b, c&#xff1a;表示存…

数据结构(六):树与二叉树

一、树的基本概念树的定义树&#xff08;Tree&#xff09;是由 n&#xff08;n ≥ 0&#xff09;个节点组成的有限集合&#xff0c;当 n 0 时称为空树。非空树中&#xff1a;有且仅有一个根节点&#xff08;Root&#xff09;&#xff1b;其余节点可以划分为若干个互不相交的子…

《Linux运维总结:Shell 脚本日志输出工具》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、Shell 脚本日志输出工具 1、提供的 logger() 函数是一个非常实用的 Shell 脚本日志输出工具&#xff0c;它支持带时间戳和…

select ... for update阻塞

总结阻塞规则&#xff1a;当前事务持有的锁 (来自 SELECT ... FOR UPDATE)其他事务尝试的操作是否会被阻塞&#xff1f;原因排他锁 (X Lock) 在行 R 上SELECT ... FROM ... (普通查询)否读快照 (MVCC)&#xff0c;不需要锁排他锁 (X Lock) 在行 R 上SELECT ... FROM ... FOR UP…

LangChain4j终极指南:Spring Boot构建企业级Agent框架

LangChain4j Spring Boot 构建企业级 Agent 框架深度指南&#xff08;3000字终极版&#xff09;一、架构设计&#xff1a;面向未来的企业级智能体系统1.1 分层架构设计1.2 核心组件职责1.3 企业级特性设计二、核心模块深度实现2.1 智能体协作引擎&#xff08;LangGraph4j高级应…

前端基础之《Vue(29)—Vue3 路由V4》

一、安装1、命令cnpm install vue-router42、配置映射为src路径&#xff08;1&#xff09;安装对应配置cnpm install types/node&#xff08;2&#xff09;配置vite.config.tsimport { defineConfig } from vite import vue from vitejs/plugin-vue import * as path from &quo…

9.2 通过DuEDrawingControl把eDrawing嵌入到C#中显示

本文介绍如何通过DuEDrawingControl控件在C#的WPF中进行3D的显示。 DuEDrawingControl在实际应用中可以应用于以下场景: 1.CAD文件预览:在Winform或WPF应用程序中,用户可以预览装配文件、工程图文件等,方便进行设计和审核。 2.打印管理:控件支持打印文件的管理,用…

《Vuejs设计与实现》第 13 章(异步组件和函数式组件

目录 13.1 异步组件的问题与解决方法 13.2 异步组件的实现原理 3.2.1 封装 defineAsyncComponent 函数 13.2.2 超时与 Error 组件 13.2.3 延迟与 Loading 组件 13.2.4 重试机制 13.3 函数式组件 13.4 总结 在第12章&#xff0c;我们深入探讨了组件的基本含义和实现方式…

Python的七大框架对比分析

谈到“Python 七大框架”时&#xff0c;通常指 Django、Flask、FastAPI、Tornado、Sanic、AIOHTTP 和 Pyramid 这七位“常驻嘉宾”。它们各有气质&#xff0c;适合的场景也截然不同。1. DjangoDjango 像一辆全副武装的重型越野&#xff1a;出厂就配好 ORM、后台管理、权限、缓存…

Redis中String数据结构为什么以长度44为embstr和raw实现的分界线?

​ 一道常见Redis面试题。 ​ 在Redis的String数据结构中&#xff0c;当字符串的实际长度小于44且包含非整数字符时底层编码方式为embstr。当超过44时使用raw底层编码方式。 ​ 那么为什么要以字符串的长度44为分界线呢&#xff1f; 信息一 ​ 首先要分析embst…

告别人工巡查,校园空调管理迈入智能物联高效时代

在“双碳”战略深入推进和智慧校园建设加速落地的背景下&#xff0c;学校空调的用电管理已经不再是“开与关”的简单问题&#xff0c;而是涵盖了能效优化、安全保障、智慧化管理的综合课题。蓝奥声科技凭借LPIOT低功耗物联网、ECWAN边缘协同网络等优势技术&#xff0c;打造出面…