并发设计模式实战系列(10):Balking(犹豫模式)

🌟 大家好,我是摘星! 🌟

今天为大家带来的是并发设计模式实战系列,第10章Balking(犹豫模式),废话不多说直接开始~

目录

一、核心原理深度拆解

1. 状态守护机制

2. 与状态模式的区别

二、生活化类比:自动售货机

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

1. 完整可运行代码

2. 关键实现技术

四、横向对比表格

1. 相似模式对比

2. 线程安全方案选择

五、高级应用技巧

1. 组合模式增强

2. 日志增强实现

3. Spring应用场景

六、Balking模式变体与扩展(续)

1. 分布式场景下的Balking

2. 分级Balking策略

七、性能优化与陷阱规避

1. 状态检查的性能优化

2. 常见陷阱与解决方案

八、工业级应用案例

1. Tomcat连接器中的Balking

2. 电商库存扣减场景

九、与其他模式的组合应用

1. Balking + Observer 模式

2. Balking + Chain of Responsibility

十、终极对比表格:Balking模式家族


一、核心原理深度拆解

1. 状态守护机制

┌───────────────┐       ┌───────────────┐
│   Client      │──────>│   GuardedObj   │
└───────────────┘       ├───────────────┤│ - state       ││ - checkState()││ - changeState() └───────────────┘
  • 状态检查:通过原子操作验证对象是否处于可处理状态
  • 条件拦截:当状态不满足时立即放弃操作(Balking)
  • 线程安全:所有状态变更必须加锁(synchronized或CAS)

2. 与状态模式的区别

  • Balking:直接放弃不符合条件的请求(快速失败)
  • State Pattern:将行为委托给不同状态对象处理

二、生活化类比:自动售货机

系统组件

现实类比

核心行为

Client

顾客投币

发起购买请求

checkState

货品检测系统

检查库存和金额是否充足

Balking

退币机制

条件不满足时立即退币

  • 典型场景:当检测到「缺货」或「金额不足」时,立即终止交易流程

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

1. 完整可运行代码

import java.util.concurrent.atomic.*;// 带Balking模式的文件自动保存
public class AutoSaveEditor {// 状态标记(原子操作)private final AtomicBoolean changed = new AtomicBoolean(false);private final AtomicInteger autoSaveCount = new AtomicInteger(0);// 状态守护方法public void autoSave() {// STEP 1: 状态检查if (!changed.getAndSet(false)) {System.out.println("[Balking] 无修改不保存");return; // 快速返回}// STEP 2: 实际保存操作doSave();}// 修改内容后触发状态变更public void editDocument(String newContent) {System.out.println("编辑内容: " + newContent);changed.set(true);}private void doSave() {System.out.println("自动保存第" + autoSaveCount.incrementAndGet() + "次...");// 模拟IO操作try { Thread.sleep(500); } catch (InterruptedException e) {}}// 测试用例public static void main(String[] args) throws InterruptedException {AutoSaveEditor editor = new AutoSaveEditor();// 第一次修改(应触发保存)editor.editDocument("Version1");editor.autoSave();// 连续修改不保存(状态被消费)editor.editDocument("Version2");editor.editDocument("Version3");editor.autoSave(); // 只会保存一次// 无修改情况editor.autoSave();}
}

2. 关键实现技术

// 1. 原子状态标记
private final AtomicBoolean changed = new AtomicBoolean(false);// 2. 状态检查与重置一体化操作
changed.getAndSet(false) // 3. 线程安全计数器
autoSaveCount.incrementAndGet()

四、横向对比表格

1. 相似模式对比

模式

核心策略

适用场景

Balking

条件不满足立即放弃

状态校验场景(如自动保存)

Retry

条件不满足循环重试

网络请求等可恢复场景

State

委托给状态对象处理

复杂状态转换场景

Guard Suspension

等待条件满足

必须完成的阻塞任务

2. 线程安全方案选择

实现方式

优点

缺点

synchronized

简单可靠

性能开销较大

AtomicXXX

无锁高性能

只适用于简单状态

ReentrantLock

可中断/超时

需手动释放锁

volatile

轻量级可见性保证

不保证复合操作原子性


五、高级应用技巧

1. 组合模式增强

// 结合Guard Suspension模式实现超时控制
public boolean autoSaveWithTimeout(long timeout) throws InterruptedException {long start = System.currentTimeMillis();while (!changed.get()) {if (System.currentTimeMillis() - start > timeout) {return false; // 超时放弃}Thread.sleep(50);}return doSave();
}

2. 日志增强实现

// 记录Balking事件
if (!changed.get()) {auditLogger.log("Balking at " + LocalDateTime.now());return;
}

3. Spring应用场景

@Component
public class ConfigMonitor {@Scheduled(fixedRate = 5000)public void reloadConfig() {if (!GlobalConfig.isDirty()) {return; // Balking}// 重新加载配置...}
}

好的!我将延续原有结构,从 第六部分 开始扩展Balking模式的深度内容,保持技术解析的连贯性和完整性。


六、Balking模式变体与扩展(续)

1. 分布式场景下的Balking

// 使用Redis实现分布式状态标记
public class DistributedBalking {private final Jedis jedis;private static final String LOCK_KEY = "resource:lock";public boolean tryProcess(String resourceId) {// SETNX实现原子状态检查(分布式锁原理)Long result = jedis.setnx(LOCK_KEY, "locked");if (result == 0) {System.out.println("[Distributed Balking] 资源已被占用");return false;}jedis.expire(LOCK_KEY, 30);return true;}
}

关键点

  • 使用Redis的SETNX命令替代本地原子变量
  • 需设置过期时间避免死锁
  • 适用于微服务抢单、定时任务调度等场景

2. 分级Balking策略

// 根据业务重要性实现分级放弃
public class PriorityBalking {private enum Priority { HIGH, NORMAL, LOW }public void process(Priority priority) {if (!checkResource()) {if (priority == Priority.LOW) {System.out.println("低优先级任务放弃");return;}// 高优先级任务等待资源waitForResource();}// 执行处理...}
}

七、性能优化与陷阱规避

1. 状态检查的性能优化

优化手段

实现方式

适用场景

双重检查锁

先非阻塞检查,再同步块内二次检查

高并发读场景

状态标记分组

对不同资源分桶标记

多资源竞争场景

延迟状态重置

处理完成后再重置状态(减少CAS竞争)

短时高频状态变更

// 双重检查锁实现示例
public class DoubleCheckBalking {private volatile boolean busy = false;public void execute() {if (!busy) {  // 第一次非阻塞检查synchronized (this) {if (!busy) {  // 第二次原子检查busy = true;// 执行任务...busy = false;}}}}
}

2. 常见陷阱与解决方案

陷阱现象

根本原因

解决方案

活锁(Livelock)

多个线程持续检查-放弃循环

引入随机退避时间

状态逃逸

对象引用被外部修改

防御性拷贝(Deep Copy)

监控缺失

无法追踪放弃操作次数

添加Metrics计数器


八、工业级应用案例

1. Tomcat连接器中的Balking

// org.apache.tomcat.util.net.AbstractEndpoint
public boolean processSocket(SocketWrapperBase<S> socket) {if (running && !paused) {// 将socket交给线程池处理return executor.execute(new SocketProcessor(socket));}// 服务未运行立即放弃return false; 
}

设计启示

  • 通过runningpaused双状态判断
  • 放弃时直接关闭Socket连接释放资源

2. 电商库存扣减场景

public class InventoryService {private final AtomicInteger stock = new AtomicInteger(100);public boolean deductStock(int quantity) {int current = stock.get();if (current < quantity) {// 库存不足立即返回metrics.log("balking:insufficient_stock"); return false;}// CAS原子扣减return stock.compareAndSet(current, current - quantity);}
}

九、与其他模式的组合应用

1. Balking + Observer 模式

public class ConfigMonitor {private final List<Listener> listeners = new CopyOnWriteArrayList<>();private volatile String currentConfig;// 配置变更通知(Balking条件检查)public void updateConfig(String newConfig) {if (Objects.equals(currentConfig, newConfig)) {return; // 配置未变化时放弃}this.currentConfig = newConfig;notifyListeners();}
}

2. Balking + Chain of Responsibility

public abstract class OrderHandler {private OrderHandler next;public void handle(Order order) {if (canHandle(order)) {// 实际处理逻辑...} else if (next != null) {next.handle(order);} else {// 责任链终止时的Balkingorder.fail("NO_HANDLER_FOUND");}}protected abstract boolean canHandle(Order order);
}

十、终极对比表格:Balking模式家族

变体名称

核心差异点

典型应用场景

Java SDK中的体现

经典Balking

基于本地原子变量

单机资源控制

AtomicBoolean.getAndSet

分布式Balking

依赖外部存储状态

跨服务协调

Redis SETNX

分级Balking

按优先级差异化处理

业务流量分级

ThreadPoolExecutor拒绝策略

延迟Balking

超时后才放弃

弱依赖服务调用

Future.get(timeout)

批量Balking

累积多个请求后统一判断

批量处理系统

BufferedWriter.flush

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

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

相关文章

【强化学习系列】贝尔曼方程

首先回顾状态价值函数和动作价值函数的定义&#xff1a; 状态价值函数 v π ( s ) v_\pi(s) vπ​(s)是从状态 s s s出发&#xff0c;直至一幕结束后获得的回报的期望值 动作价值函数 q π ( s , a ) q_\pi(s,a) qπ​(s,a)是从状态 s s s出发&#xff0c;采取动作 a a a后&…

donet使用指定版本sdk

ps:来自微软官方方案,实测可行,就是在项目任意目录下在新建 global.json,并配置sdk版本 SDK 使用最新安装的版本 SDK 命令包括 dotnet new 和 dotnet run。 .NET CLI 必须为每个 dotnet 命令选择一个 SDK 版本。 即使在以下情况下&#xff0c;它也会默认使用计算机上安装的最新…

x-cmd install | Orbiton:极简至上的终端文本编辑器与轻量级 IDE

目录 核心特点安装适用场景优势 厌倦了臃肿复杂的 IDE&#xff1f;渴望一个轻巧、快速、专注的编码环境&#xff1f;Orbiton&#xff0c;一款极简主义的终端文本编辑器与轻量级 IDE&#xff0c;将带给你前所未有的编码体验。 核心特点 极简主义&#xff0c;专注编码&#xff1…

大脑、机器人与贝叶斯信念及AI推理

在机器不再局限于重复性任务的世界里&#xff0c;机器人技术已经大胆地迈入了感知、学习和决策的领域。这篇文章探讨了智能机器人系统是如何构建的——从理解它们嘈杂的传感器和不确定的环境&#xff0c;到使它们能够做出明智的选择并随着时间的推移调整自己的行为。 AI推理 …

线上婚恋相亲小程序源码介绍

​基于ThinkPHP、FastAdmin和UniApp开发的线上婚恋相亲小程序源码&#xff0c;这款小程序源码采用了ThinkPHP作为后端框架&#xff0c;其强大的功能与良好的扩展性为程序的稳定运行提供了保障。 ​FastAdmin作为后台管理框架&#xff0c;使得管理员能够便捷地对用户信息、相亲…

长短期记忆(LSTM)简介

RNN 的主要限制在于它无法记住很长的序列&#xff0c;并且会陷入梯度消失的问题。 什么是梯度消失问题&#xff1f; 当添加更多具有某些激活函数的层时&#xff0c;神经网络中损失函数的梯度趋近于零&#xff0c;这使得网络难以训练。 长短期记忆&#xff08;LSTM&#xff09;…

JESD204B 探究

JESD204B协议是高速串行接口标准,主要用于ADC/DAC与逻辑器件(如FPGA)之间的数据传输。以下为综合解析: 一、协议概述 ‌核心作用‌ 通过高速SERDES技术实现数模转换器与逻辑器件间的高效数据传输,支持多通道同步和确定性延迟,适用于GB级吞吐量场景23。‌版本演进‌ JESD2…

Flutter PIP 插件 ---- 新增PipActivity,Android 11以下支持自动进入PIP Mode

接上文 Flutter PIP 插件 ---- Android 项目地址 PIP&#xff0c; pub.dev也已经同步发布 pip 0.0.3&#xff0c;你的加星和点赞&#xff0c;将是我继续改进最大的动力 开发文档 Add videos using picture-in-picture (PiP)介绍PIP功能从 Android 8.0 (API level 26) 引入&…

【Java开发日记】6个Java 工具,轻松分析定位 JVM 问题 !

目录 使用 JDK 自带工具查看 JVM 情况 jps jinfo jvisualvm jcm 使用 JDK 自带工具查看 JVM 情况 JDK 自带了很多命令行甚至是图形界面工具&#xff0c;帮助查看 JVM 的一些信息。比如&#xff0c;在机器上运行 ls 命令&#xff0c;可以看到 JDK 8 提供了非常多的工具或程…

动态规划简单题2

leetcode91题&#xff08;解码方法&#xff09; 分析题目&#xff1a; 1.这是一种解码&#xff0c;就是给多个数字组成的字符串&#xff0c;把这些数字解码成字母&#xff0c;看看一共有多少种 2.如果一个数字前有前导0就不合法&#xff0c;比如06&#xff0c;这与6不同&…

(007)Excel 公式的使用

文章目录 逻辑运算公式的参数常用函数引用方式引用工作表和工作簿表格的引用修改公式的计算时机区域交叉引用 逻辑运算 公式的参数 单元格引用&#xff1a;SUM(A1:A24)。字面值&#xff1a;SQRT(121)。字面文本字符串&#xff1a;PROPER(“john.f.smith”)。表达式&#xff1a…

Unity 和 Unreal Engine(UE) 两大主流游戏引擎的核心使用方法

以下是 Unity 和 Unreal Engine&#xff08;UE&#xff09; 两大主流游戏引擎的核心使用方法和对比分析&#xff0c;帮助开发者快速上手并根据项目需求选择合适工具&#xff1a; 一、Unity 使用指南 1. 安装与配置 安装&#xff1a;从 Unity Hub 下载&#xff0c;选择长期支持…

猜数字游戏:从数学原理到交互体验的完整设计指南

目录 猜数字游戏&#xff1a;从数学原理到交互体验的完整设计指南引言第一章 游戏数学原理1.1 均匀分布与随机生成1.2 最优猜测策略 第二章 游戏系统设计2.1 核心架构2.2 动态难度系统 第三章 交互设计细节3.1 输入验证系统3.2 渐进式提示机制 第四章 进阶功能设计4.1 智能辅导…

2025工业大模型白皮书 | 蚂蚁工厂北京航空航天大学联合出品

由蚂蚁工厂与北京航空航天大学联合发布的《2025工业大模型白皮书》是一部针对工业领域大模型技术发展的前瞻性研究报告。该白皮书系统梳理了工业大模型的技术演进、核心应用场景、关键挑战及未来发展趋势&#xff0c;旨在为制造业数字化转型提供理论支撑和实践指南。作为产学研…

JavaWeb:后端web基础(TomcatServletHTTP)

一、今日内容 二、Tomcat 介绍与使用 介绍 基本使用 小结 配置 配置 查找进程 三、Servlet 什么是Servlet 快速入门 需求 步骤 1.新建工程-模块&#xff08;Maven&#xff09; 2.修改打包方式-war 3.编写代码 /*** 可以选择继承HttpServlet*/ WebServlet("/hello&q…

构建现代分布式云架构的三大支柱:服务化、Service Mesh 与 Serverless

目录 前言1. 服务化架构模式&#xff1a;构建可扩展的基础单元1.1 服务化的定义与演进1.2 在分布式云中的价值1.3 面临的挑战 2. Service Mesh 架构&#xff1a;服务通信的治理中枢2.1 什么是 Service Mesh&#xff1f;2.2 功能与优势2.3 在分布式云中的角色2.4 落地难点 3. Se…

嵌入式C语言的运算符与输入输出

目录 1. 运算符 1.1 位运算符 1.1.1 位运算 ~ 1.1.2 位逻辑与 & 1.1.3 位逻辑或 | 1.1.4 位逻辑异或 ^ 1.1.5 位移位运算 1.1.6 将无符号位的某位快速置 1 1.2 三目运算符 1.3 逗号运算符 1.4 运算符优先级 2. 输出 2.1 字符输出函数 2.2 格式输出函数 2.3 字符…

IPD研学:76页页基于IPD思想-华为需求管理培训方案【附全文阅读】

适应人群 本方案适用于企业中参与产品研发、市场、销售、项目管理等部门的人员,尤其是负责需求管理工作的相关从业者;致力于提升产品竞争力,对优化需求管理流程、提高产品开发质量感兴趣的企业管理者;以及希望了解行业前沿需求管理方法,寻求突破和创新的相关人士。…

米酒的功能和优缺点

米酒&#xff08;又称甜酒、酒酿&#xff09;是一种以糯米或其他谷物为原料&#xff0c;经发酵制成的传统发酵饮品&#xff0c;酒精度较低&#xff08;通常1%-10%&#xff09;。以下是其功能、优点及缺点分析&#xff1a; 一、米酒的功能 营养补充 富含B族维生素&#xff08;B1…

注册登录页面项目

关系型数据库地址&#xff1a;C:\Users\ASUS\AppData\Local\Temp\HuaweiDevEcoStudioDatabases\rdb #注册页面register.ets import dataRdb from ohos.data.rdbconst STORE_CONFIG {name: weather4.db } const TABLE_NAME weather_info const SQL_CREATE_TABLE CREATE TAB…