验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

多线程为何要用锁机制

阅读:758 来源:乙速云 作者:代码code

多线程为何要用锁机制

简单来说:多线程要用锁,是因为多个线程同时访问“共享数据”时,会发生数据竞争,导致程序结果不可预测甚至崩溃。

下面从原因到本质逐步解释。


一、为什么多线程会有问题?

假设有两个线程同时做这件事:

int count = 0;

count++;

你以为流程是:

线程A:count = 0 → 1
线程B:count = 1 → 2

但实际上,count++ 并不是一步完成的,它至少包含三步:

  1. 读取 count 的值
  2. 计算 count + 1
  3. 写回 count

如果两个线程交叉执行,可能会变成:

线程A:读到 count = 0
线程B:读到 count = 0
线程A:计算 0 + 1
线程B:计算 0 + 1
线程A:写回 1
线程B:写回 1

最终结果:只加了一次,但预期是两次。

这种问题就叫 竞态条件(Race Condition)


二、什么时候必须用锁?

只要满足下面三个条件,就可能需要锁:

  1. 多线程
  2. 访问共享资源(变量、文件、数据库、内存)
  3. 至少有一个线程会“写”它

✅ 只读:不需要锁
❌ 有写:必须考虑锁


三、锁的作用是什么?

锁的核心作用是 保证“临界区”的原子性和可见性

1️⃣ 原子性(Atomicity)

保证一段代码 要么全部执行完,要么完全不执行,中间不会被其他线程打断。

2️⃣ 可见性(Visibility)

保证一个线程对共享数据的修改,其他线程能立刻看到。


四、锁是怎么解决问题的?

以 Java 为例:

synchronized (lock) {
    count++;
}

执行逻辑变成:

  • 线程 A 先拿到锁
  • 线程 B 必须等
  • 线程 A 执行完,释放锁
  • 线程 B 才能进入

这样就不会出现上面的“同时读到 0”的问题。


五、不用锁会怎样?

可能出现的问题包括:

  • ✅ 计算结果错误
  • ✅ 数据不一致
  • ✅ 程序逻辑混乱
  • ✅ 偶发 Bug(最难查)
  • ✅ 高并发下崩溃

而且这类 Bug 不可复现、难调试


六、锁不是唯一方案(进阶)

锁是最通用的方案,但不是唯一方案:

方案 适用场景
锁(synchronized / Lock) 通用
原子类(AtomicInteger) 简单计数
不可变对象 安全但受限
线程本地变量(ThreadLocal) 不共享
无锁算法(CAS) 高性能场景

七、一句话总结

多线程要用锁,是因为多个线程同时修改共享数据时,会导致数据竞争和不一致,锁用来保证同一时间只有一个线程进入关键代码区,从而保证程序的正确性。

如果你愿意,我可以用 C / C++ / Java / Python 的具体例子,或者画一张“时间线图”帮你更直观理解。

分享到:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>