并发设计模式实战系列(2):领导者/追随者模式

 

🌟 ​大家好,我是摘星!​ 🌟

今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~

目录

领导者/追随者(Leader/Followers)

为什么需要领导者/追随者(Leader/Followers)模式?

一、核心原理深度拆解

1. 角色轮转机制

2. 关键技术实现

二、生活化类比:医院分诊系统

三、Java代码实现(生产级Demo)

1. 完整可运行代码

2. 关键机制说明

四、横向对比表格

1. 线程模型对比

2. 性能优化策略对比

五、高级实践技巧

1. 动态Leader选举优化

2. 负载均衡策略

3. 监控关键指标

六、总结与适用场景

1. 核心优势

2. 典型应用场景

3. 模式局限


领导者/追随者(Leader/Followers)

为什么需要领导者/追随者(Leader/Followers)模式?

在现代高并发系统中,我们面临一个关键挑战:
高并发监听 vs. 高效任务处理

  • 监听瓶颈:传统Reactor模式中,单个Selector线程可能成为性能瓶颈(如10万+连接时)
  • 线程竞争:多线程同时监听同一Selector会导致epoll_ctl锁竞争(Linux内核级锁)
  • 上下文切换:任务队列的生产者-消费者模型引入额外调度开销

领导者/追随者模式通过角色轮换机制解决这一矛盾:

  • Leader线程:独占监听权限,避免多线程竞争Selector
  • Follower线程:无监听开销,专注处理任务
  • 动态切换:处理事件后立即移交领导权,实现负载均衡

一、核心原理深度拆解

1. 角色轮转机制

              +-----------------+|  事件到达        |+--------+--------+|+-----------v-----------+ | Leader线程监听事件     |←----++-----------+-----------+     || 处理事件        |+-----------v-----------+     || 指定新Leader          |     |+-----------+-----------+     ||                 |+-----------v-----------+     || Follower晋升为Leader  |-----++-----------------------+
  • 三阶段工作流
    1. 监听事件:Leader线程独占监听资源(如Selector)
    2. 事件分派:检测到事件后指定新Leader
    3. 角色转换:原Leader转为Worker处理事件,新Leader继续监听

2. 关键技术实现

  • 线程状态管理:使用AtomicInteger记录角色状态(LEADER=0, PROCESSING=1, FOLLOWER=2)
  • 无锁化设计:通过CAS操作实现Leader选举
  • 事件分发器:维护ThreadPool保存所有工作线程

二、生活化类比:医院分诊系统

系统组件

现实类比

核心行为

Leader线程

导诊台护士

识别患者类型,分配接诊医生

Follower线程

诊室医生

专注处理当前患者

事件队列

候诊区座位

缓冲等待处理的患者

  • 工作流程
    1. 导诊护士(Leader)发现新患者
    2. 指定空闲医生(新Leader)接替导诊工作
    3. 原护士转为医生处理当前患者

三、Java代码实现(生产级Demo)

1. 完整可运行代码

import java.nio.channels.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;public class LeaderFollowersServer {private static final int MAX_THREADS = 8;private final AtomicInteger leaderStatus = new AtomicInteger(0); // 0=可用, 1=忙碌// 线程工作单元class Worker implements Runnable {private final Selector selector;private volatile boolean isLeader = false;public Worker(Selector selector) {this.selector = selector;}@Overridepublic void run() {while (!Thread.interrupted()) {try {// 尝试成为Leaderif (leaderStatus.compareAndSet(0, 1)) {isLeader = true;System.out.println(Thread.currentThread().getName() + " 成为Leader");// 监听事件(非阻塞模式)selector.selectNow();for (SelectionKey key : selector.selectedKeys()) {if (key.isAcceptable()) {handleAccept((ServerSocketChannel) key.channel());}}// 移交Leader身份leaderStatus.set(0);isLeader = false;} else {// 作为Follower处理事件TimeUnit.MILLISECONDS.sleep(100);}} catch (Exception e) {e.printStackTrace();}}}private void handleAccept(ServerSocketChannel server) {try {SocketChannel client = server.accept();System.out.println(Thread.currentThread().getName() + " 处理连接: " + client);// 模拟业务处理TimeUnit.MILLISECONDS.sleep(500);} catch (Exception e) {e.printStackTrace();}}}public void start() throws Exception {Selector selector = Selector.open();ServerSocketChannel ssc = ServerSocketChannel.open();ssc.bind(new java.net.InetSocketAddress(8080));ssc.configureBlocking(false);ssc.register(selector, SelectionKey.OP_ACCEPT);ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS);for (int i = 0; i < MAX_THREADS; i++) {pool.execute(new Worker(selector));}}public static void main(String[] args) throws Exception {new LeaderFollowersServer().start();}
}

2. 关键机制说明

// CAS实现无锁选举
if (leaderStatus.compareAndSet(0, 1)) { // 成功获取Leader身份
}// 优雅退出处理
selector.wakeup(); // 唤醒阻塞的select()
pool.shutdownNow(); // 关闭线程池

四、横向对比表格

1. 线程模型对比

特性

Leader/Followers

Half-Sync/Half-Async

Reactor

上下文切换

少(角色转换)

中等

多(事件传递)

资源消耗

低(固定线程数)

中等

吞吐量

高(无锁设计)

极高

适用场景

短连接服务

混合型任务

纯异步任务

编程复杂度

高(需处理状态转换)

中等

2. 性能优化策略对比

优化方向

Leader/Followers

传统线程池

CPU利用率

通过角色切换减少竞争

依赖队列管理

内存消耗

固定线程数控制

动态扩容可能OOM

延迟稳定性

更均匀的任务分配

存在长尾效应

扩展性

水平扩展需重新设计

容易增加线程数


五、高级实践技巧

1. 动态Leader选举优化

// 使用Phaser实现协调
Phaser phaser = new Phaser(1);
while (true) {phaser.arriveAndAwaitAdvance();// 选举新Leader...
}

2. 负载均衡策略

// 基于处理能力的Leader选择
if (worker.getLoad() < threshold) {promoteToLeader(worker);
}

3. 监控关键指标

// Leader切换频率监控
AtomicLong leaderChangeCount = new AtomicLong();// 线程负载统计
ConcurrentHashMap<Worker, Integer> workloadMap = new ConcurrentHashMap<>();

六、总结与适用场景

1. 核心优势

低竞争:单线程监听 + 动态Leader选举,减少锁争用
高吞吐:无队列中转,事件直接由工作线程处理
资源可控:固定线程数,避免OOM风险

2. 典型应用场景

  • 短连接服务:如HTTP API网关、游戏服务器
  • 低延迟系统:金融交易订单处理
  • 均匀负载场景:任务处理耗时差异小的业务

3. 模式局限

⚠️ 不适合长任务:Leader长时间占用会导致监听阻塞
⚠️ 实现复杂度高:需精细控制线程状态转换

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

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

相关文章

自求导实现线性回归与PyTorch张量详解

目录 前言一、自求导的方法实现线性回归1.1自求导的方法实现线性回归的理论讲解1.1.1 线性回归是什么&#xff1f;1.1.2线性回归方程是什么&#xff1f;1.1.3散点输入1.2参数初始化1.2.1 参数与超参数1.2.1.1 参数定义1.2.1.2 参数内容1.2.1.3 超参数定义1.2.1.4 超参数内容1.…

2025年机电一体化、机器人与人工智能国际学术会议(MRAI 2025)

重要信息 时间&#xff1a;2025年4月25日-27日 地点&#xff1a;中国济南 官网&#xff1a;http://www.icmrai.org 征稿主题 机电一体化机器人人工智能 传感器和执行器 3D打印技术 智能控制 运动控制 光电系统 光机电一体化 类人机器人 人机界面 先进的运动控制 集成制造系…

线性代数 | 知识点整理 Ref 3

注&#xff1a;本文为 “线性代数 | 知识点整理” 相关文章合辑。 因 csdn 篇幅合并超限分篇连载&#xff0c;本篇为 Ref 3。 略作重排&#xff0c;未整理去重。 图片清晰度限于引文原状。 如有内容异常&#xff0c;请看原文。 《线性代数》总复习要点、公式、重要结论与重点释…

CFD中的动量方程非守恒形式详解

在计算流体力学&#xff08;CFD&#xff09;中&#xff0c;动量方程可以写成守恒形式和非守恒形式&#xff0c;两者在数学上等价&#xff0c;但推导方式和应用场景不同。以下是对非守恒形式的详细解释&#xff1a; 1. 动量方程的守恒形式 首先回顾守恒形式的动量方程&#xff…

Leetcode 1504. 统计全 1 子矩形

1.题目基本信息 1.1.题目描述 给你一个 m x n 的二进制矩阵 mat &#xff0c;请你返回有多少个 子矩形 的元素全部都是 1 。 1.2.题目地址 https://leetcode.cn/problems/count-submatrices-with-all-ones/description/ 2.解题方法 2.1.解题思路 单调栈 时间复杂度&…

【Docker】运行错误提示 unknown shorthand flag: ‘d‘ in -d ----详细解决方法

使用docker拉取Dify的时候遇到错误 错误提示 unknown shorthand flag: d in -dUsage: docker [OPTIONS] COMMAND [ARG...]错误原因解析 出现 unknown shorthand flag: d in -d 的根本原因是 Docker 命令格式与当前版本不兼容&#xff0c;具体分为以下两种情况&#xff1a; 新…

华为OD机试真题——攀登者2(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《攀登者2…

qt硬件与软件通信中 16进制与十进制转化

1. 首先上代码, 这是在qt语言上的操作 截取 01 03 0C 00 00 00 00 00 00 00 0C 00 0C 00 0C 93 70 这串16进制数值进行处理&#xff0c;截取这样一段内容 00 0C 00 0C 00 0C 字节数组转字符串。从bytearray数组转换为string. QString CustomTcpSocket::recieveInfo() {QByteArr…

图形变换算法

一、学习目的 &#xff08;1&#xff09;掌握多面体的存储方法。 &#xff08;2&#xff09;掌握图形的几何变换及投影变换。 &#xff08;3&#xff09;掌握三维形体不同投影方法的投影图的生成原理。 &#xff08;4&#xff09;掌握多面体投影图绘制的编程方法。 二、学…

【JAVAFX】自定义FXML 文件存放的位置以及使用

情况 1&#xff1a;FXML 文件与调用类在同一个包中&#xff08;推荐&#xff09; 假设类 MainApp 的包是 com.example&#xff0c;且 FXML 文件放在 resources/com/example 下&#xff1a; 项目根目录 ├── src │ └── sample │ └── Main.java ├── src/s…

Ubuntu20.04安装企业微信

建议先去企业微信官网看一下有没有linux版本&#xff0c;没有的话在按如下方式安装&#xff0c;不过现在是没有的。 方案 1、使用docker容器 2、使用deepin-wine 3、使用星火应用商店 4. 使用星火包deepin-wine 5、使用ukylin-wine 本人对docker不太熟悉&#xff0c;现…

CSS appearance 属性:掌握UI元素的原生外观

在现代网页设计中&#xff0c;为了达到一致的用户体验&#xff0c;我们有时需要让HTML元素模仿操作系统的默认控件样式。CSS中的appearance属性提供了一种简便的方式来控制这些元素是否以及如何显示其默认外观。本文将详细介绍appearance属性&#xff0c;并通过实际代码示例来展…

十四、C++速通秘籍—函数式编程

目录 上一章节&#xff1a; 一、引言 一、函数式编程基础 三、Lambda 表达式 作用&#xff1a; Lambda 表达式捕获值的方式&#xff1a; 注意&#xff1a; 四、函数对象 函数对象与普通函数对比&#xff1a; 五、函数适配器 1、适配普通函数 2、适配 Lambda 表达式 …

大模型Rag-指令调度

本文主要记录根据用户问题指令&#xff0c;基于大模型做Rag&#xff0c;匹配最相关描述集进行指令调度&#xff0c;可用于匹配后端接口以及展示答案及图表等。 1.指令查询处理逻辑 1.实现思路 指令识别&#xff1a;主要根据用户的问题q计算与指令描述集is [i0, ... , im]和指…

音视频学习 - ffmpeg 编译与调试

编译 环境 macOS Ventrua 13.4 ffmpeg 7.7.1 Visual Studio Code Version: 1.99.0 (Universal) 操作 FFmpeg 下载源码 $ cd ffmpeg-x.y.z $ ./configure nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.If you think configure made a mistake…

golang-常见的语法错误

https://juejin.cn/post/6923477800041054221 看这篇文章 Golang 基础面试高频题详细解析【第一版】来啦&#xff5e; 大叔说码 for-range的坑 func main() { slice : []int{0, 1, 2, 3} m : make(map[int]*int) for key, val : range slice {m[key] &val }for k, v : …

音视频之H.265/HEVC预测编码

H.265/HEVC系列文章&#xff1a; 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 预测编码是视频编码中的核心技术之一。对于视频信号来说&#xff0c;一幅图像内邻近像素之间有着较强的空间相关性,相邻图像之…

基于政务问答的dify接口请求测试

Dify 的智能体后端服务 API 为开发者提供便捷方式&#xff0c;能让前端应用直接调用大语言模型能力。在请求时&#xff0c;需先前往应用左侧导航的 “API Access” 部分&#xff0c;在此可查看文档和管理访问凭据。为保障安全&#xff0c;API 密钥应通过后端调用&#xff0c;避…

VMware Workstation 保姆级 Linux(CentOS) 创建教程(附 iso)

文章目录 一、下载二、创建 一、下载 CentOS-7.9-x86_64-DVD-2009.iso 二、创建 VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包)

扩增子分析|基于R语言microeco包进行微生物群落网络分析(network网络、Zi-Pi关键物种和subnet子网络图)

一、引言 microeco包是福建农林大学姚敏杰教授团队开发的扩增子测序集成分析。该包综合了扩增子测序下游分析的多种功能包括群落组成、多样性、网络分析、零模型等等。通过简单的几行代码可实现复杂的分析。因此&#xff0c;microeco包发表以来被学界广泛关注&#xff0c;截止2…