分布式与可重入性的一些问题

一、分布式是什么?

分布式是指一个系统由多个独立的计算机节点组成,这些节点通过网络通信、协调工作,对外像一台计算机一样提供服务。

核心特点

  • 多个节点:物理或虚拟机上运行独立进程。
  • 消息通信:节点间通过 RPC、HTTP、消息队列等交换信息。
  • 无共享架构:通常不共享内存或时钟,各自有本地资源。
  • 部分失败:某个节点挂了,系统整体还能运行(但可能降级)。

简单例子

一个网站的后端由 10 台服务器组成,用户请求被负载均衡分发到其中一台;用户感觉不到是多台机器。


二、分布式锁的用途

分布式锁用于在分布式环境中控制**多个进程(或节点)**对共享资源的互斥访问。

典型用途

  • 防止重复执行
    比如定时任务调度,只希望集群中一个节点执行,避免重复扣款、重复发邮件。
  • 保护共享资源
    例如更新数据库中的同一行记录、操作共享文件、修改 Redis 中的计数值。
  • 解决竞态条件
    多个服务同时修改同一订单状态,用锁保证顺序。
  • 实现领导者选举
    利用锁(如 etcd、ZooKeeper 的临时顺序节点)让只有一个节点成为主节点。

与单机锁(如 Java synchronized)的区别:单机锁只能锁住同一个 JVM 内的线程,分布式锁能锁住不同机器上的进程。


三、可重入性是什么?为什么要使用同一把锁?

1. 可重入性定义

可重入锁 (Reentrant Lock)指的是:同一个线程(或同一个客户端)在已经持有某把锁的情况下,可以再次成功获取该锁,而不会被阻塞

锁内部会记录持有锁的线程(或客户端标识)和一个重入次数

  • 第一次获取:次数 = 1
  • 再次获取(重入):次数 +1
  • 释放一次:次数 -1,直到次数为 0 时真正释放锁。

2. 为什么要用同一把锁,而不是不同的锁或者干脆只上一次锁?

关键问题:为什么可重入要求的是"同一把锁"?

假设有一个场景:某个方法 doWork() 需要加锁,而它内部又调用了另一个也需要同一资源锁的方法 subWork()

  • 如果使用同一把锁(可重入)
    doWork 获得锁 L,调用 subWork 时发现锁 L 已经被当前线程持有,直接放行(重入计数+1)。
    结果:正常工作,避免死锁。

  • 如果使用不同的锁
    doWork 获得锁 L1,subWork 需要锁 L2。

    此时如果 L1 和 L2 保护的是同一资源(例如同一个银行账户),用两个不同锁就无法互斥------其他线程可能通过 L2 同时修改资源,破坏一致性。

  • 为什么一个线程要"两次获取同一把锁"?只外层上一次锁,不就行了吗?

    因为内层函数可能被单独调用,它必须自己保证线程安全。如果为了迁就外层调用而取消内层的锁,就会破坏内层函数的封装性和安全性。

核心原因

  • 可重入要求"同一把锁"是为了在同一个线程内避免死锁(当嵌套调用需要同一资源时)。
  • 如果换成不同的锁,要么失去互斥性(不同的锁保护同一资源),要么失去可重入语义(新锁对象与旧锁无关)。

简单记忆:可重入 = 同一个锁对象 + 持有者身份 + 计数。如果不是同一个锁,就无法判断"当前线程是否已经拥有对该资源的访问权",也就无法实现安全的重入。


四、总结

问题 回答
为什么不只上一次锁? 因为内层函数(如 transferOut)可能被其他不持有锁的上下文调用,它必须自己加锁才能保证安全。
为什么需要同一把锁两次? 外层函数调用了内层函数,两者需要保护同一资源(如账户余额),必须用同一把锁。可重入锁允许同一线程重复获取,避免死锁。
如果不用可重入锁怎么办? 要么忍受死锁,要么破坏封装(传递锁状态参数),要么代码重复(写两个版本的方法)。

一句话总结 :可重入锁让你在保持方法独立线程安全 的同时,又能安全地嵌套调用这些方法。

相关推荐
小江的记录本8 分钟前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka
身如柳絮随风扬8 小时前
多数据源切换实战:从业务场景到3种实现方案全解析
java·分布式·微服务
AIMath~9 小时前
雪花算法+ZooKeeper解决方案+RPC是什么
分布式·zookeeper·云原生
KmSH8umpK9 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第六篇
数据库·redis·分布式
空中海11 小时前
Kafka :存储、复制与可靠性
分布式·kafka·linq
渣渣盟11 小时前
构建企业级实时数据管道:Kafka + Flink 最佳实践
分布式·flink·kafka
KmSH8umpK12 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第四篇
数据库·redis·分布式
KmSH8umpK12 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第五篇
数据库·redis·分布式
卧室小白13 小时前
ceph-分布式存储
分布式
aXin_ya13 小时前
微服务第九天 分布式缓存(Redis)
分布式·缓存·微服务