智用指南
第二套高阶模板 · 更大气的阅读体验

线程锁机制怎么用?实战讲解让你轻松上手

发布时间:2025-12-31 10:00:30 阅读:68 次

写过多线程程序的人都知道,多个线程同时操作同一个资源时,很容易出问题。比如两个线程同时往一个变量加1,结果可能只加了一次。这就是典型的“竞态条件”。要解决这个问题,就得靠线程机制。

为什么需要线程锁

想象一下你和室友共用一个冰箱,你们俩同时发现里面没牛奶了,于是都决定去买。结果就是,两个人各带一盒回来,家里多了盒多余的牛奶。在程序里,这种“重复操作”可能导致数据错乱、资源浪费,甚至系统崩溃。

线程锁的作用就是让某个代码段在同一时间只能被一个线程执行,其他线程得等着,等锁释放了才能进来。就像你去厨房做饭,先锁上门,别人只能等你做完出来再进。

常见的锁类型和使用方式

以 Python 为例,最常用的锁是 threading 模块里的 Lock:

import threading
import time

# 创建一个锁对象
counter_lock = threading.Lock()
shared_counter = 0

def worker():
    global shared_counter
    for _ in range(100000):
        counter_lock.acquire()  # 加锁
        shared_counter += 1     # 操作共享资源
        counter_lock.release()  # 释放锁

# 启动两个线程
t1 = threading.Thread(target=worker)
t2 = threading.Thread(target=worker)
t1.start()
t2.start()
t1.join()
t2.join()

print(shared_counter)  # 输出 200000,不会出错

上面这段代码中,每次修改 shared_counter 前都先 acquire 锁,改完后再 release。这样就能保证任何时候只有一个线程在改这个变量。

更简洁的写法是用 with 语句,自动加锁和释放:

def worker():
    global shared_counter
    for _ in range(100000):
        with counter_lock:
            shared_counter += 1

这种写法不容易忘记释放锁,推荐日常使用。

注意死锁问题

锁虽然好用,但用不好会“卡住”。比如两个线程各自拿着一把锁,又想拿对方的,结果谁也动不了,这就叫死锁。

避免死锁的关键是:统一加锁顺序。比如多个锁时,大家都按 A→B→C 的顺序来申请,就不会互相堵住。

其他类型的锁

除了基本的 Lock,还有 RLock(可重入锁),允许同一线程多次获取同一个锁,适合递归调用场景。还有 Semaphore 控制并发数量,像限制同时最多3个线程访问某资源。

实际开发中,比如做抢票系统、库存扣减、日志写入,都会用到锁机制。只要涉及共享数据,就得考虑线程安全。

别以为只有Python才要管这个,Java 的 synchronized、Go 的 sync.Mutex、C++ 的 std::mutex,原理都差不多。掌握一种,其他语言迁移起来很快。