You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程操作非共享变量时:可共用同一锁还是需用多锁?

线程锁使用疑问解答

核心问题解答

能否为操作独立变量的线程共用同一把锁?

可以,但完全没必要——甚至会拖慢程序性能。

你的第一个示例里,两个线程分别操作完全独立的var1和var2,它们的操作本来不会互相干扰,不需要互斥逻辑。但如果共用同一把Lock,两个线程会被强制串行执行:第一个线程拿到锁修改变量时,第二个线程必须等锁释放才能执行,白白浪费了多线程并行的优势,还额外增加了锁竞争的开销。

哪种实现方式更优?

显然第二个示例使用两把独立的Lock是更好的选择。
因为两个变量属于完全独立的共享资源,为它们分配专属锁,既能保证单个变量操作的线程安全,又能让两个线程并行执行,最大化利用多线程的性能优势。

补充说明:你的示例代码中var = 1是局部变量赋值,不会修改外部的var1/var2(因为列表是可变对象,但这里直接覆盖了函数内的引用)。实际业务中如果要修改外部变量的内容(比如var.append(1)),才需要锁来保护操作的原子性。

多把锁的适用场景

  • 独立资源并行处理:当多个线程操作完全独立的共享资源时,用多把锁可以让各线程同时执行,避免不必要的串行等待,提升整体运行效率。
  • 细粒度锁优化性能:面对复杂数据结构(如拆分的哈希表、分块存储的数据集),不同部分的修改互不影响,给每个部分分配独立的锁,能在保证线程安全的同时,大幅减少锁竞争概率,提升并发处理能力。
  • 降低死锁风险(需谨慎设计):在嵌套锁的场景中,合理拆分锁的粒度,配合严格的锁获取顺序,可以降低死锁的发生概率。

修正后的代码示例

共用单锁(不推荐)

from threading import Thread, Lock
from time import sleep

def task(lock, var):
    with lock:
        # 实际业务中修改可变对象内容时才需要锁
        var.append(1)
    sleep(5)

lock = Lock()
var1 = []
var2 = []

Thread(target=task, args=(lock, var1)).start()
Thread(target=task, args=(lock, var2)).start()

使用独立锁(推荐)

from threading import Thread, Lock
from time import sleep

def task(lock, var):
    with lock:
        var.append(1)
    sleep(5)

lock1 = Lock()
lock2 = Lock()
var1 = []
var2 = []

Thread(target=task, args=(lock1, var1)).start()
Thread(target=task, args=(lock2, var2)).start()

内容的提问来源于stack exchange,提问作者alec_djinn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:57:34