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

并发设计模式实战系列(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长时间占用会导致监听阻塞
⚠️ 实现复杂度高:需精细控制线程状态转换

相关文章:

  • SS25001-多路复用开关板
  • 010数论——算法备赛
  • 航电系统通信与数据链技术分析
  • 15 nginx 中默认的 proxy_buffering 导致基于 http 的流式响应存在 buffer, 以 4kb 一批次返回
  • 编程常见错误归类
  • 第五届能源工程、新能源材料与器件国际学术会议(NEMD 2025)
  • 使用VHD虚拟磁盘安装双系统,避免磁盘分区
  • 每天学一个 Linux 命令(23):file
  • 电能质量治理解决方案:构建高效、安全的电力系统
  • 前端:uniapp中uni.pageScrollTo方法与元素的overflow-y:auto之间的关联
  • 《软件设计师》复习笔记(11.2)——开发方法、产品线、软件复用、逆向
  • docker部署springboot(eureka server)项目
  • 网安加·百家讲坛 | 刘志诚:AI安全风险与未来展望
  • 8.观察者模式:思考与解读
  • 3D机器视觉激光器在智能制造领域的主要应用
  • 【LeetCode】大厂面试算法真题回忆(61)--组装新的数组
  • 电子电器架构 --- OEM企标中规定ECU启动时间的目的
  • 基于C++(MFC)的细胞识别程序
  • 焊接机器人的设计
  • CVE-2023-46604漏洞复现与深度分析
  • 耐克领跑女性运动市场:持续加码、创新,更多新增长点有望涌现
  • 护航民营企业出海,上海设37家维权工作站、建立近百人专家团队
  • GDP增长4.1%,一季度广东经济数据出炉
  • 石中英已任新成立的清华大学教育学院院长
  • 复旦大学附属中山医院也有儿科了,门诊将于下月底开业
  • 中小企业收款难何解?快速认定企业身份并理顺付款责任链条