volatile 能保证什么,不能保证什么
这篇我想按“排查记录”来写,主题是 volatile 能保证什么,不能保证什么。这种写法比纯概念文更适合我自己回看。 现象先别急着解释volatile 解决可见性和有序性,不保证复合操作原子性。 先把现象钉住,比急着下结论有用。很多时候真正的关键不是“答案是什么”,而是“我是怎么一步步排到这里的”。 我会先看哪几件事 状态标记适合 volatile count++ 仍然不是原子操作 需要原子性时考虑锁或 Atomic 类 带入一...
ReentrantLock 比 synchronized 多了什么
这篇按踩坑笔记来写,因为 ReentrantLock 比 synchronized 多了什么 我现在更容易记住“错在哪”,而不是“定义长什么样”。 先记住这句话理解可中断、可超时、公平锁和条件队列。 很多问题不是不会用,而是用得太顺手了,顺手到把边界条件给省掉了。 这类问题一般怎么出现我脑子里会先放这个场景:用 tryLock 给库存扣减加一个快速失败分支。 一开始看着都像是个小问题,真正麻烦的是它往往不是立刻报错,而是跑一阵子、...
线程、进程和并发问题的基本认识
今天把 线程、进程和并发问题的基本认识 补成一篇正常一点的学习笔记,不写大而全,就记我这轮最想吃透的部分。 一句话先立住先区分执行单元,再讨论共享资源。 我这次真正记住的点 进程隔离资源 线程共享进程内存 并发问题来自共享可变状态 为什么我会专门记这块因为它很容易出现一种错觉:看资料的时候觉得自己会了,真到写接口、改 SQL、配事务、看线程池参数时又开始发虚。 我现在尽量把知识点挂到一个具体场景上:用两个线程同时累加同一个计数器...
synchronized 的锁对象到底是谁
今天不想写长文,先把 synchronized 的锁对象到底是谁 这块拆成几条短一点的问答。面试里经常会被连续追问,如果只背一句定义,第二问基本就卡住了。 先说我自己的结论锁住的是对象监视器,不是代码片段本身。 我现在会先把这类题分成“定义是什么、为什么这样设计、代码里怎么用、容易翻车在哪”四层去答。这样比死背一段话稳很多。 快问快答 实例方法锁当前对象。我现在的理解:先记结论,再回到代码里找一个能验证它的场景。 静态方法锁 Cl...
枚举类在业务状态流转里的用法
这篇我想按“排查记录”来写,主题是 枚举类在业务状态流转里的用法。这种写法比纯概念文更适合我自己回看。 现象先别急着解释把状态码、描述和允许的流转放到同一个语义里。 先把现象钉住,比急着下结论有用。很多时候真正的关键不是“答案是什么”,而是“我是怎么一步步排到这里的”。 我会先看哪几件事 枚举能减少魔法字符串 状态流转要校验前置状态 数据库保存 code 而不是 ordinal 带入一个排查场景实现订单从待支付到已取消、已支付的...
BigDecimal 金额计算为什么容易出错
这篇按踩坑笔记来写,因为 BigDecimal 金额计算为什么容易出错 我现在更容易记住“错在哪”,而不是“定义长什么样”。 先记住这句话金额计算要控制精度、舍入和构造方式。 很多问题不是不会用,而是用得太顺手了,顺手到把边界条件给省掉了。 这类问题一般怎么出现我脑子里会先放这个场景:实现订单总价、优惠和实付金额计算。 一开始看着都像是个小问题,真正麻烦的是它往往不是立刻报错,而是跑一阵子、数据一多、并发一上来才暴露。 这次我想盯...
Java 时间 API:LocalDateTime 使用笔记
今天不想写长文,先把 Java 时间 API:LocalDateTime 使用笔记 这块拆成几条短一点的问答。面试里经常会被连续追问,如果只背一句定义,第二问基本就卡住了。 先说我自己的结论区分日期、时间、时区和时间戳。 我现在会先把这类题分成“定义是什么、为什么这样设计、代码里怎么用、容易翻车在哪”四层去答。这样比死背一段话稳很多。 快问快答 LocalDateTime 不包含时区。我现在的理解:先记结论,再回到代码里找一个能验...
Lambda 表达式在业务代码里的边界
今天把 Lambda 表达式在业务代码里的边界 补成一篇正常一点的学习笔记,不写大而全,就记我这轮最想吃透的部分。 一句话先立住用 Lambda 减少样板代码,同时保留调试友好性。 我这次真正记住的点 函数式接口适合策略差异 复杂逻辑不要塞进一行表达式 异常处理要显式设计 为什么我会专门记这块因为它很容易出现一种错觉:看资料的时候觉得自己会了,真到写接口、改 SQL、配事务、看线程池参数时又开始发虚。 我现在尽量把知识点挂到一个...