- 博客(2983)
- 收藏
- 关注
原创 HoRain云--Java AtomicLong 与 LongAdder 实战:并发计数的选择边界
本文对比了Java中AtomicLong与LongAdder在并发计数场景下的适用边界。AtomicLong适用于需精确值、唯一编号或条件更新的场景,保证线性化语义;而LongAdder通过分段累加降低高并发竞争,适合频繁更新、偶尔读取的统计指标。两者均不适用于限流、去重等需原子判断的场景。选择时应根据业务是否依赖严格时序与唯一性,结合性能测试与实际负载综合评估。
2026-11-06 09:56:11
181
原创 HoRain云--Java ProcessBuilder 实战:启动子进程、读取输出与超时终止
ProcessBuilder 用于安全调用外部程序,但需避免命令注入、输出阻塞与进程泄漏。应分离命令与参数,及时消费标准/错误输出,设置超时并优雅终止子进程。校验退出码与输出内容,限制工作目录与环境变量,妥善管理资源。建议将外部调用封装为有明确协议的适配器,结合隔离、限流与测试,确保安全可靠。
2026-11-06 09:54:33
140
原创 HoRain云--Java FileChannel 实战:文件锁、并发写入与关闭边界
Java 多进程写文件需依赖操作系统级 FileLock 协调,因对象锁无法跨 JVM 生效。FileLock 提供独占或共享锁,保护文件区域访问,但不保证内容一致性或外部工具遵守。正确使用需确保锁与通道按逆序关闭,结合原子替换、临时文件和 force() 保障持久化。锁仅解决访问冲突,不替代数据校验、版本控制或事务机制。实际应用中应验证平台差异,避免覆盖旧文件,通过测试确保断电恢复与异常处理可靠性。
2026-11-06 09:53:09
225
原创 HoRain云--Java ReentrantReadWriteLock 实战:读多写少缓存的一致性边界
ReentrantReadWriteLock 适用于读多写少场景,通过读锁并发、写锁独占提升性能。缓存加载需双重检查避免重复加载,但锁内应仅限快速操作,慢加载宜异步或拆分键粒度。注意锁降级/升级逻辑,避免死锁;读写锁仅保障单机一致性,需配合版本控制、过期策略与监控。避免在读锁中修改状态或返回可变对象,失败处理应谨慎,防止误判故障。
2026-11-06 09:51:05
147
原创 HoRain云--Java Semaphore 实战:限制并发访问与资源许可
Semaphore 用于控制对有限资源的并发访问,与线程池不同,它限制的是资源使用上限而非任务调度。通过许可机制,确保同时访问资源的任务数不超过容量,避免资源耗尽。使用时需在 finally 中释放许可,防止死锁;应结合线程池、资源池和超时策略,合理设置许可数,并监控等待时间与失败率。避免将信号量用于无限资源或非关键路径,确保其仅保护真实受限资源。
2026-11-06 09:50:16
264
原创 HoRain云--Java ThreadLocal 实战:线程池复用下的上下文隔离与清理
ThreadLocal 在线程池中易引发数据泄漏,因工作线程复用导致上下文跨请求传播。关键在于任务结束后必须通过 try/finally 显式调用 remove(),确保清理。避免在异常路径或提前返回时遗漏清理,且不可依赖垃圾回收。敏感信息、大对象不应存入,上下文应仅保留必要标识。复杂场景需封装任务包装器,显式传递上下文,优先使用参数传递而非隐式依赖。测试应验证线程复用与异常路径,代码审查聚焦设置与清理的匹配性。核心原则:设置与清理绑定于同一任务,边界清晰可维护。
2026-11-05 10:00:53
177
原创 HoRain云--Java HttpClient 实战:请求超时、响应校验与资源关闭
JDK HttpClient 可高效完成常见 HTTP 调用,但可靠性依赖完整边界设计:需复用客户端、区分连接与请求超时、校验状态码及响应体、合理处理重试与幂等性,并通过集中配置、异步优化与监控保障稳定性。测试本地服务可有效覆盖异常路径,确保失败场景可控。
2026-11-05 09:59:52
239
原创 HoRain云--Java ByteBuffer 实战:用长度字段处理 TCP 半包与粘包
TCP 是有序字节流,不保留消息边界,read 可能读取半包或粘包。需在应用层定义协议,如用四字节长度字段标识消息体,配合 ByteBuffer 的 flip、compact、mark/reset 实现增量解码。必须校验长度上限,防止内存攻击;明确字符集(如 UTF-8),避免平台差异。解码器应无副作用,解码后交由独立线程处理业务,避免阻塞网络。需严格测试半包、粘包、非法数据等场景,并考虑跨平台、字节序、版本兼容与背压控制,确保协议可靠、安全、可复用。
2026-11-05 09:58:20
112
原创 HoRain云--Java ExecutorCompletionService 实战:按完成顺序消费并发任务
ExecutorCompletionService 将任务提交与结果获取解耦,支持按完成顺序处理异步结果,避免队头阻塞。它不改变线程池行为,而是通过完成队列实现结果的有序消费。适用于批量查询、并行校验等“先到先处理”场景,但需自行处理超时、取消、异常和背压。关键在于合理设计任务管理、错误处理与进度监控,确保系统稳定与业务一致性。
2026-11-05 09:57:32
163
原创 HoRain云--Java CompletableFuture 实战:异步编排、异常恢复与超时边界
CompletableFuture 通过组合式异步编程,实现多任务并行与依赖管理。关键在于合理使用 thenApply、thenCompose、thenCombine 分离转换、依赖与合并逻辑;通过 exceptionally、handle 等处理异常,避免吞异常;设置显式超时(orTimeout/completeOnTimeout)并配合业务线程池,保障资源可控。避免滥用默认公共池、频繁 join 或忽略取消信号。建议按准备、并行、汇总、输出分层设计,返回稳定状态模型,确保可测性、可观测性与可维护性。
2026-11-05 09:56:09
149
原创 HoRain云--Java ObjectInputFilter 实战:反序列化边界与类型白名单
Java 原生反序列化存在安全风险,需通过 ObjectInputFilter 实施白名单策略与资源限制。示例展示如何限制类类型、深度、引用数和字节数,仅允许可信对象(如 SafeMessage、String 及短数组)反序列化,拒绝不可信类型与恶意构造的复杂对象图。过滤器应尽早设置,避免在业务层处理已反序列化的对象。建议结合显式格式(如 JSON、Protobuf)替代原生序列化,实现更安全的跨服务通信。
2026-11-04 09:59:12
89
原创 HoRain云--Java ForkJoinPool 分治实战:RecursiveTask 的拆分边界与线程池隔离
ForkJoinPool 适用于可拆分的 CPU 密集型任务,通过 RecursiveTask 实现分治计算。合理设置阈值(如 2000)平衡并行与开销,采用 fork/compute/join 模式提升效率。建议使用独立线程池以控制并行度与生命周期,避免在任务中阻塞。任务应只读输入、返回结果,确保数据正确性;浮点运算需注意舍入差异。测试与监控关键,性能验证需预热、重复测量,并结合真实负载评估收益。
2026-11-04 09:58:30
133
原创 HoRain云--Java WatchService 实战:构建可靠的目录变更监听器
WatchService 可监听目录的文件创建、修改和删除事件,但不保证事件唯一或文件写入完成。生产中需结合文件大小、命名规则等判断文件稳定。示例展示可关闭的目录监听器,通过 take 获取事件,处理时确保文件安全读取,避免误判。
2026-11-04 09:57:50
54
原创 HoRain云--Java Phaser 实战:把多阶段并发任务组织成可关闭的流程
Phaser 适用于动态参与、多阶段协作的批量任务,通过阶段号协调参与者同步。它不处理任务队列或异常传播,需手动管理注册、到达、等待与注销。示例展示三阶段流程:初始化注册、校验、发布,主线程与工作线程协同推进。关键点包括:正确区分 arrive、awaitAdvance 与 arriveAndDeregister;避免重复注册或提前注销;异常与取消需独立设计;线程池容量应匹配并发需求。使用时应画清阶段时间线,确保资源清理与结果一致性。
2026-11-04 09:57:02
142
原创 HoRain云--Java StampedLock 实战:乐观读不是无锁读,版本校验才是关键
StampedLock 乐观读通过标记验证实现高效读取,适用于读多写少场景。正确流程为:先 tryOptimisticRead 取标记,读取数据后调用 validate 校验一致性,失败则回退至读锁重读。关键在于完整快照必须在锁内生成,避免跨线程不一致。乐观读非无锁,需配合重试机制;不支持可重入,且性能依赖读写比例与冲突频率。使用时应确保数据快照不可变、外部操作锁外执行,并通过充分测试验证正确性与性能。
2026-11-04 09:56:23
180
原创 HoRain云--Java 超时与重试实战:指数退避为什么还需要总预算和幂等保护?
重试机制需谨慎设计:仅对瞬时故障(如网络波动)重试,拒绝非法请求、认证失败等不可重试场景。应结合次数上限、时间预算与指数退避策略,避免无限重试或超时。示例代码通过分类异常、动态计算剩余时间与随机抖动,实现安全可靠的重试逻辑,确保幂等性与系统稳定性。
2026-11-03 09:23:31
140
原创 HoRain云--Java ZIP 解压安全实战:防目录穿越,还要限制哪些资源?
本文介绍安全解压压缩包的关键措施,重点防范Zip Slip等路径穿越攻击。通过规范化路径、严格校验文件名、限制目录层级与大小,并确保目标目录为新建独占目录,有效防止外部输入导致的目录逃逸、资源耗尽等问题。示例代码展示了如何在不依赖扩展名判断的前提下,实现安全的压缩包解压。
2026-11-03 09:22:23
158
原创 HoRain云--Java ReentrantLock 与 Condition 实战:等待、唤醒和关闭应该怎样配合?
线程协作中,锁仅解决互斥,条件变量才处理状态等待。正确使用需以状态为等待依据,而非通知;必须循环检查谓词,避免虚假唤醒。通过条件变量与明确关闭协议结合,实现可中断、可关闭的线程安全通道。signalAll用于关闭时唤醒所有等待者,防止挂起;await释放锁,避免死锁。临界区应短小,业务逻辑移出锁外。测试需覆盖状态转换全场景,确保可靠性。
2026-11-03 09:21:17
148
原创 HoRain云--Java ConcurrentHashMap 实战:线程安全的 Map,为什么仍然会产生并发漏洞?
ConcurrentHashMap 仅保证单键操作的线程安全,不等于业务流程原子性。计数丢失、重复初始化等问题源于将容器安全误解为流程安全。应使用 merge、computeIfAbsent 等原子操作,避免拼接多步调用;值对象需不可变或有并发协议;跨键一致性须显式设计,如聚合更新或事务。测试应覆盖竞态、异常与删除重建场景。最终,正确使用并发工具的关键在于:理解其边界,匹配业务语义,而非依赖“自动安全”。
2026-11-03 09:20:02
171
原创 HoRain云--Java 虚拟线程实战:线程更便宜之后,为什么接口还是会被压垮?
虚拟线程降低阻塞任务的线程成本,但不解决数据库连接、网络吞吐等真实资源瓶颈。应将任务并发与资源许可分离,使用信号量限制下游访问,并结合限流、超时、取消机制保障系统稳定。迁移时需关注锁、上下文和内存开销,压测应聚焦延迟、错误率与资源占用,而非线程数量。从报表接口渐进改造,通过对比验证收益,确保业务逻辑不受技术变更影响。
2026-11-03 09:19:04
147
原创 HoRain云--Java 字符串避坑:从 char、Unicode 码点到 UTF-8 编码边界
本文剖析字符串长度定义的模糊性,指出“昵称最多十个字”背后隐藏的编码、码点、代码单元与用户感知字符四大长度陷阱。通过Java示例展示如何按码点精确截取、严格处理UTF-8错误、规范化文本,并强调接口契约需明确定义单位。提出从测试到部署全程统一规则,避免前后端差异与乱码问题,确保系统在表情、重音、跨平台场景下稳定可靠。
2026-11-02 09:41:51
101
原创 HoRain云--Java SPI 实战:用 ServiceLoader 实现可插拔扩展
SPI(服务提供者接口)通过定义统一扩展契约,实现接口与实现的解耦。主程序仅依赖接口,运行时通过ServiceLoader发现并选择具体实现,避免硬编码条件分支。关键在于:约定清晰接口、独立交付实现、显式按业务标识选择、启动阶段校验加载结果,并建立契约测试与兼容性管理机制。适用于需灵活扩展且实现独立维护的场景,但需权衡引入复杂性与收益,避免过早使用。
2026-11-02 09:41:03
159
原创 HoRain云--Java 定时任务避坑:ScheduledExecutorService 的周期、异常与关闭
本文深入探讨定时任务调度的边界问题,剖析scheduleAtFixedRate与scheduleWithFixedDelay的语义差异,揭示异常处理、任务取消、线程池管理及跨进程协调等关键陷阱。通过实例展示任务失败后自动抑制、恢复机制与资源清理策略,强调应分离周期触发与失败重试逻辑,避免并发冲突与资源泄漏。最终倡导以可观测性、幂等设计和明确退出协议构建健壮的调度系统。
2026-11-02 09:40:11
409
原创 HoRain云--Java BlockingQueue 实战:用有界队列构建可控的生产消费流程
本文通过一个任务流水线案例,揭示了队列积压导致内存回收与崩溃的根本原因:缺乏容量边界与背压机制。强调有界队列作为业务边界的必要性,需结合任务大小、下游瓶颈合理设定容量;指出阻塞操作的选择应基于是否允许阻塞,而非方法名;通过完整示例展示停止标记的协议设计与退出机制;提醒线程安全不等于可随意共享对象,需注意可见性与所有权;最后倡导监控入队等待、失败率等指标,将背压转化为调用方可理解的状态反馈,实现系统稳定与业务一致性。
2026-11-02 09:39:11
270
原创 HoRain云--Java Comparator 排序实战:多字段、空值与比较契约一次讲清
本文通过完整示例阐述如何将复杂排序需求转化为可解释、可测试的比较器。强调先明确字段优先级、空值处理与方向规则,使用Comparator.comparing链式组合避免嵌套错误;建议仅局部反转评分而非整链,确保空值顺序正确;指出排序影响集合去重与分页一致性,需区分展示与唯一性;提倡以契约驱动测试,覆盖边界场景,并在变更时通过固定优先级与回归测试保障落地。核心是:清晰契约 + 可测实现 = 稳定排序。
2026-11-02 09:38:17
268
原创 HoRain云--Java classpath 资源读取实战:本地运行与 JAR 部署别踩坑
在 Java 项目中,应通过类加载器的 getResourceAsStream 读取 classpath 资源,而非使用 new File()。JAR 包中的资源位于内部,不可直接作为文件路径访问。推荐使用 try-with-resources 确保流关闭,并注意路径前导斜杠、编码(如 UTF-8)及大小写一致性。默认配置可打包于 classpath,但敏感或环境相关配置应外部化。构建后需验证 JAR 内资源存在,并在独立环境中测试启动,确保配置正确加载。
2026-10-30 09:45:53
75
原创 HoRain云--Java Record 实战:用记录类表达不可变数据与校验不变量
Java 16 引入的 record 简化了纯数据类的定义,自动生成构造器、访问器、equals、hashCode 和 toString,适合语义上由数据构成的值对象。通过紧凑构造器可校验与规范化参数,但组件为浅层不可变,集合类型需防御性拷贝。不适用于有独立身份、可变生命周期或依赖框架特性的 ORM 实体,也需警惕敏感信息日志泄露及序列化兼容问题。建议用于查询结果、事件载荷、命令参数等场景,注意命名与结构变更对 API 的影响。
2026-10-30 09:45:17
159
原创 HoRain云--Java 正则表达式实战:输入校验、分组提取与性能边界
正则表达式适用于清晰文本格式匹配,但易引发可读性差、过度匹配及ReDoS风险。Java中应区分matches()(整串校验)与find()(局部搜索),合理使用static final Pattern提升性能。避免复杂正则验证邮箱、电话等,优先基础校验+专用解析器。注意转义、捕获组、回溯优化与输入长度限制,关键规则应附业务说明与测试用例。复杂场景推荐使用专用解析器,正则仅用于边界明确的匹配与提取。
2026-10-30 09:44:40
46
原创 HoRain云--Java 17 HttpClient 实战:超时、响应体与连接复用
Java 11 的 HttpClient 提供了高效、可复用的 HTTP 客户端能力,支持同步与异步调用。需合理配置连接与请求超时,选择合适的响应体处理器以避免内存溢出。必须显式检查状态码,区分成功与可重试失败。重试需确保操作幂等,并纳入总超时预算。生产环境应使用 HTTPS、安全凭据管理,避免敏感信息泄露。通过并发控制、背压和日志脱敏保障稳定性与安全性。
2026-10-30 09:44:05
164
原创 HoRain云--Java JDBC 事务实战:提交、回滚与批处理边界
“先扣库存,再创建订单”需通过数据库事务保证原子性。使用JDBC时,应关闭自动提交,将相关SQL置于同一连接的事务中,检查更新行数防止超卖,并在异常时回滚。事务仅保障数据库操作一致性,外部调用如HTTP、消息需用事务消息或Outbox模式处理。避免长事务,缩短锁持有时间,合理设置隔离级别,通过并发测试验证正确性。生产中应依赖连接池与框架事务管理,确保连接状态恢复,关键操作设计幂等,以应对提交结果不确定和死锁问题。
2026-10-30 09:43:25
81
原创 HoRain云--GraalVM Native Image 实战——Java 云原生的“最后一公里”
双12大促中,订单服务因JVM冷启动延迟(28秒)导致扩容失效。GraalVM NativeImage通过AOT编译将启动时间降至毫秒级,内存占用降低90%。文章详解其原理、SpringBoot 3.x适配实践、量化对比及五大踩坑点,提出“按场景选型”策略:Serverless、边缘计算等短生命周期负载优先用Native;长驻高吞吐服务仍可保留JVM。结合ZGC与虚拟线程,构建云原生时代Java的完整技术栈。
2026-10-29 09:45:49
167
原创 HoRain云--Spring Boot 3.x 云原生三件套——虚拟线程、AOT 与可观测性的工程化落地
SpringBoot 3.x以Java17和Jakarta EE9+为基线,通过虚拟线程、AOT编译与GraalVM原生镜像、第一流可观测性三大能力,实现从“开发框架”向“云原生运行时”的跃迁。虚拟线程可零代码提升I/O密集型服务吞吐,但需关注JDK版本、连接池配置及观测兼容性;AOT显著缩短启动时间(秒级→毫秒级),降低内存占用,适用于Serverless等场景,但构建耗时增加且动态特性受限;可观测性由手动集成升级为自动配置,@Observation提供细粒度观测能力,需配合TraceId进行链路追踪。三
2026-10-29 09:45:18
141
原创 HoRain云--分代 ZGC——亚毫秒级 GC 停顿的生产落地指南
ZGC自JDK11引入,历经演进至JDK25已成唯一模式,实现亚毫秒级停顿,核心依赖着色指针、读屏障与极短STW。分代ZGC显著提升吞吐量,实测停顿降为1.2ms,CPU利用率降低18%。大厂实践显示卡顿降20倍,吞吐升4倍。选型应基于堆大小与延迟敏感度;调优需先确认问题是否真由GC引起,避免误判。
2026-10-29 09:44:48
60
原创 HoRain云--记录模式 + 密封类 + Switch 模式匹配——Java 类型系统的“黄金三角”实战
Java17引入密封类、Java21正式支持记录模式与Switch模式匹配,三者组合实现对封闭类型层级的穷尽性编译检查。密封类限定子类型,记录模式实现解构式类型检查,Switch模式确保所有分支被覆盖,编译器替代运行时发现遗漏。该“黄金三角”显著提升代码安全性与可维护性,尤其适用于API响应体、状态机等场景,推动Java从“语法糖”迈向类型系统表达力跃升。
2026-10-29 09:43:56
45
原创 HoRain云--Java 虚拟线程深度实战——从平台线程到百万级并发的范式迁移
虚拟线程的价值不在于“让每个请求变快”,而在于把并发规模从“受操作系统线程数约束”释放到“受堆内存和业务逻辑约束”。它让 Java 开发者可以用同步的、可读的代码写出接近响应式编程的并发能力,而不必被迫引入 Reactor 式的异步心智负担。JDK 24 对钉死的修复补齐了最后一块关键短板,2026 年是将虚拟线程从“技术预研”推进到“生产默认”的合适窗口期。
2026-10-29 09:43:07
216
原创 HoRain云--Java 运行时注解与反射实战:写一个轻量字段校验器
Java 集合的“不可修改”不等于不可变。Collections.unmodifiableList 返回只读视图,仍受原集合影响;List.copyOf 创建独立快照,与源分离。前者适合隐藏写权限,后者保障结果稳定。防御性拷贝可防止外部修改内部状态,但仅浅拷贝元素,需注意可变对象引用。不可修改集合非线程安全,共享时需配合同步机制或使用 CopyOnWriteArrayList。API 设计应明确语义,通过命名和文档区分视图、快照与副本,避免因误解导致并发问题或配置异常。
2026-10-28 09:32:03
285
原创 HoRain云--Java 集合的“不可修改”不等于不可变:视图、快照与防御性拷贝
Java 集合的“不可修改”不等于不可变。Collections.unmodifiableList 返回只读视图,仍受原集合影响;List.copyOf 创建独立快照,与源分离。前者适合隐藏写权限,后者保障结果稳定。防御性拷贝可防止外部修改内部状态,但仅浅拷贝元素,需注意可变对象引用。不可修改集合非线程安全,共享时需配合同步机制或使用 CopyOnWriteArrayList。API 设计应明确语义,通过命名和文档区分视图、快照与副本,避免因误解导致并发问题或配置异常。
2026-10-28 09:31:26
140
原创 HoRain云--Java ThreadLocal 实战:线程上下文如何设置、传递与清理
ThreadLocal 适用于线程内上下文传递,如请求编号、租户标识等,但需在 finally 中调用 remove() 清理,避免线程池复用导致数据泄漏。不可跨线程自动传播,异步任务需显式传递必要信息。避免存储大对象或可变状态,推荐使用作用域管理或入口层统一设置与清理,确保安全性和可观测性。
2026-10-28 09:30:49
74
原创 HoRain云--Java 枚举不只是常量:用 enum 收拢策略与业务行为
Java 枚举不仅是常量容器,更可封装与选项相关的业务行为。通过在枚举中定义抽象方法实现不同配送方式的费用计算与时效估算,避免重复的 if/else 分支,提升代码一致性与可维护性。枚举应保持无状态、使用稳定协议码映射外部输入,避免依赖 ordinal() 或 name() 作为持久化键。复杂或动态策略应交由外部服务管理,枚举仅负责分类。合理使用可减少遗漏、增强测试性,并支持演进与兼容。
2026-10-28 09:30:12
157
原创 HoRain云--Java 金额计算为什么要用 BigDecimal?从精度、舍入到比较
Java 金额计算应使用 BigDecimal 以避免二进制浮点数精度误差。double 无法精确表示十进制小数(如 0.1 + 0.2 ≠ 0.3),而 BigDecimal 支持精确十进制运算,需从字符串构造,避免中间浮点转换。关键点包括:明确舍入模式(如 HALF_UP)、使用 compareTo 比较、合理控制 scale、除法显式指定精度与舍入策略,并在领域模型中封装币种与金额逻辑。测试应覆盖边界值与规则一致性,确保跨系统对账准确。
2026-10-28 09:29:32
199
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅