兰州seo新站优化招商,怎么建网站app,创建网站根目录,做网站公司佛山锁的应用与场景#xff1a;从单机到分布式
摘要#xff1a;在多线程和分布式系统中#xff0c;“锁”是避免资源竞争、保障数据一致性的核心机制。但你真的了解锁吗#xff1f;什么时候该用锁#xff1f;用哪种锁#xff1f;本文通过通俗的比喻和代码示例#xff0c;带…锁的应用与场景从单机到分布式
摘要在多线程和分布式系统中“锁”是避免资源竞争、保障数据一致性的核心机制。但你真的了解锁吗什么时候该用锁用哪种锁本文通过通俗的比喻和代码示例带你彻底搞懂锁的应用场景 一、为什么需要锁
想象一下多人同时编辑同一份文档如果不加控制最终文档内容会乱成一锅粥。程序中的共享资源如数据库字段、文件、内存变量同样面临这个问题——锁的作用就是让多个线程/进程“排队”访问资源。
常见问题场景
订单重复处理用户疯狂点击提交订单导致重复扣款。超卖问题秒杀活动中库存被减到负数。数据覆盖两个线程同时修改用户余额后者覆盖前者结果。 二、单机环境下的锁
1. 乐观锁 vs 悲观锁
悲观锁假设一定会发生冲突先加锁再操作。 应用场景冲突频繁、临界区代码执行时间长。 实现方式 数据库SELECT ... FOR UPDATEJavasynchronized、ReentrantLock
维度synchronizedReentrantLock锁管理JVM 自动管理无需手动释放需手动获取和释放易忘记导致死锁灵活性功能简单仅支持非公平锁支持公平锁、超时、中断、多条件变量性能JVM 优化后性能接近低竞争场景更优高并发场景更灵活如 tryLock 减少竞争调试支持锁信息不易获取如等待队列长度提供 isLocked(), getQueueLength() 等方法适用场景简单同步需求如单方法内的线程安全复杂同步逻辑如多条件协调、精细控制
乐观锁假设冲突很少先操作再检查是否冲突。 应用场景读多写少、冲突概率低。实现方式 数据库版本号Version字段 CAS更新JavaAtomicInteger、StampedLock
代码示例数据库乐观锁
-- 1. 查询时获取版本号
SELECT stock, version FROM product WHERE id 1;-- 2. 更新时校验版本号
UPDATE product SET stock stock - 1, version version 1
WHERE id 1 AND version 1; -- 如果version被修改过更新失败2. 读写锁ReadWriteLock
核心思想读操作不互斥写操作互斥。应用场景读多写少如缓存系统。Java实现ReentrantReadWriteLock
ReadWriteLock rwLock new ReentrantReadWriteLock();// 读操作
rwLock.readLock().lock();
try {// 读取数据允许多个线程同时读
} finally {rwLock.readLock().unlock();
}// 写操作
rwLock.writeLock().lock();
try {// 修改数据独占锁
} finally {rwLock.writeLock().unlock();
}三、分布式锁
当服务部署在多台机器上时即使在同一台物理机上的多个容器/Pod单机锁失效必须使用分布式锁协调跨进程的资源访问。
1. 常见实现方案
方案核心原理优点缺点Redis锁SETNX 过期时间 Lua脚本删除性能高实现简单存在锁过期提前释放风险ZooKeeper创建临时顺序节点监听前序节点删除可靠性高自动释放锁性能较低需要维护ZK集群数据库锁基于唯一索引或行级锁无需额外组件性能差高并发易成瓶颈
高并发且允许偶发锁失效Redis Redisson。强一致性需求ZooKeeper 或 Etcd。简单场景数据库不推荐生产环境高频使用
2. Redis分布式锁示例Redisson实现
// 1. 获取锁对象
RLock lock redissonClient.getLock(orderLock);// 2. 尝试加锁等待10秒锁自动释放时间30秒
boolean isLocked lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {try {// 处理业务逻辑processOrder();} finally {lock.unlock();}
}四、如何选择合适的锁
1. 决策流程图 2. 黄金原则
能用单机锁就别用分布式锁复杂度陡增锁粒度要小锁住的范围越小性能越高优先考虑无锁设计如使用线程安全的类ConcurrentHashMap、本地线程存储ThreadLocal 五、避坑指南
死锁避免嵌套锁设置超时时间。锁饥饿公平锁可缓解但性能会下降。锁泄露确保finally块中释放锁。脑裂问题分布式锁选择强一致性协调器如ZooKeeper。 六、总结
单机多线程本地锁 数据库唯一索引即可满足需求无需分布式锁。优先选synchronized或ReentrantLock。多机/多实例必须引入分布式锁同时结合数据库约束保证最终安全。高并发读读写锁ReadWriteLock是救星。分布式系统Redis锁性能或ZooKeeper锁可靠性二选一。终极目标在安全性和性能之间找到平衡
技术没有银弹理解场景才能选出最合适的锁