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

一、分布式是什么?

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

核心特点

  • 多个节点:物理或虚拟机上运行独立进程。
  • 消息通信:节点间通过 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)可能被其他不持有锁的上下文调用,它必须自己加锁才能保证安全。
为什么需要同一把锁两次? 外层函数调用了内层函数,两者需要保护同一资源(如账户余额),必须用同一把锁。可重入锁允许同一线程重复获取,避免死锁。
如果不用可重入锁怎么办? 要么忍受死锁,要么破坏封装(传递锁状态参数),要么代码重复(写两个版本的方法)。

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

相关推荐
juniperhan4 小时前
Flink 系列第 3 篇:核心概念精讲|分布式缓存 + 重启策略 + 并行度 底层原理 + 代码实战 + 生产规范
大数据·分布式·缓存·flink
想你依然心痛4 小时前
HarmonyOS 5.0 IoT开发实战:构建分布式智能设备控制中枢与边缘计算网关
分布式·物联网·harmonyos
lifallen4 小时前
如何保证 Kafka 的消息顺序性?
java·大数据·分布式·kafka
橙露4 小时前
大数据处理:PySpark 入门与分布式数据分析实战
分布式·数据挖掘·数据分析
时光追逐者4 小时前
分享四款开源且实用的 Kafka 管理工具
分布式·kafka·开源
IT枫斗者4 小时前
AI Agent 设计模式全景解析:从单体智能到分布式协作的架构演进
人工智能·redis·分布式·算法·spring·缓存·设计模式
☞遠航☜7 小时前
kafka快速上手
分布式·kafka·linq
2501_9333295517 小时前
技术架构深度解析:Infoseek舆情监测系统的全链路设计与GEO时代的技术实践
开发语言·人工智能·分布式·架构
鬼先生_sir17 小时前
Zookeeper:从入门到精通
分布式·zookeeper·云原生