首页 >> 生活百科 >

lock 基础动作全套 锁机制核心操作详解

2026-11-08 23:22:01 来源:网易 编辑:曲利露 

lock 中文含义是锁,在计算机编程操作系统数据库并发场景里面,lock 基础动作全套主要包含加锁 尝试加锁 等待阻塞 释放锁 死锁检测 锁升级 锁降级这一系列标准动作,整套动作的核心目的就是解决多线程多进程并发访问共享资源的时候出现的数据错乱脏写丢失更新问题,通过 lock 把共享资源变成同一时刻只允许一个执行单元占用。之所以要掌握 lock 基础动作全套流程,是因为只要是多线程并发编程数据库事务分布式系统,都会遇到资源竞争,如果没有完整理解 lock 全套动作,很容易写出死锁 饥饿 长时间阻塞这类缺陷。学习这套内容可以按顺序推进,第一步理解 lock 的基础定义,第二步逐个学习每一个基础动作的原理,第三步了解锁的状态流转,第四步学习异常场景处理,最后区分不同类型锁对应的动作差异。lock 基础动作全套本质是一套资源占用管控流程,通过占用和释放两个核心动作,配合等待检测等辅助动作,保证共享资源并发访问安全。

lock 基础动作总览表格

动作名称英文名称动作说明
加锁lock请求获取锁,成功之后持有锁,访问共享资源
尝试加锁try lock非阻塞尝试获取锁,拿不到立刻返回失败,不进入等待
阻塞等待wait获取锁失败之后,线程进入阻塞等待状态,等待锁释放唤醒
释放锁unlock使用完共享资源之后,主动释放锁,唤醒等待队列里面的等待线程
死锁检测deadlock detect系统或者数据库识别多个执行单元互相持有锁同时等待对方锁
锁升级lock escalation细粒度锁数量过多,升级成粗粒度大锁,降低锁维护开销
锁降级lock demotion粗粒度锁释放部分权限,降成细粒度锁,提升并发能力

各个动作深度讲解

加锁 lock

这是最核心基础动作,执行单元发起锁请求,如果锁当前处于空闲状态,就成功拿到锁,标记锁为已占用,并且记录锁持有者信息。如果锁已经被别的执行单元占用,根据锁类型决定是阻塞等待还是直接返回失败。常见的互斥锁读写锁都支持这个基础加锁动作。

尝试加锁 try lock

属于非阻塞版本的加锁动作,和普通 lock 最大区别就是不会挂起线程。拿到锁就返回成功,拿不到锁马上返回失败标记,业务代码可以自己写分支处理,比如跳过本次任务或者稍后重试,适合不能长时间卡住业务的场景。

阻塞等待 wait

当普通 lock 加锁失败之后,执行单元进入等待队列,线程从运行态切换成阻塞态,不再占用 CPU 时间片。等到持有锁的执行单元执行 unlock 释放锁之后,操作系统会从等待队列挑选一个等待线程唤醒,重新竞争锁。这里会涉及公平锁和非公平锁,公平锁按照排队顺序唤醒,非公平锁允许新来线程插队竞争。

释放锁 unlock

共享资源操作完成之后必须执行 unlock,把锁标记改成空闲,清除持有者信息,同时唤醒等待队列线程。这个动作非常关键,如果业务代码异常退出没有执行 unlock,就会造成锁永久占用,也就是锁泄漏,后续所有请求都会一直阻塞。

死锁检测 deadlock detect

多个执行单元形成循环等待,线程 A 持有锁 1 等待锁 2,线程 B 持有锁 2 等待锁 1,就形成死锁。死锁检测动作会定期扫描锁等待关系,发现循环等待之后,会选择牺牲其中一个事务或者线程,回滚它的操作,释放它持有的锁,打破循环等待,数据库引擎里面这个动作是内置自动执行。

锁升级 lock escalation

细粒度锁比如行锁,当单个事务持有大量行锁的时候,锁本身的内存开销会变大,数据库会自动把大量行锁升级成表锁,这个动作就是锁升级。优点是减少锁管理消耗,缺点是并发能力下降,其他事务无法再操作这张表。

锁降级 lock demotion

和锁升级相反,把粗粒度锁降低成细粒度锁,一般在部分业务场景,持有表锁之后,业务只需要锁定少数行,主动降级成行锁,提升其他事务并发访问机会,这个动作并不是所有数据库都原生支持。

锁状态流转流程

空闲状态,锁没有持有者,可以响应 lock 请求

持有状态,已经被执行单元占用,新请求要么阻塞要么 try lock 失败

等待队列状态,多个执行单元排队等待锁释放

释放之后,锁回到空闲,唤醒等待线程重新竞争

异常相关要点

锁泄漏,加锁之后因为异常没有 unlock,锁一直保持占用

锁饥饿,高优先级线程一直抢占锁,低优先级等待线程长期拿不到锁

优先级反转,低优先级线程持有锁,高优先级线程等待它,中间高优先级任务抢占 CPU,造成高优先级任务延迟,操作系统会用优先级继承机制解决这个问题

不同锁类型动作差异

互斥锁,全套动作就是 lock try lock wait unlock

读写锁,在读锁写锁基础上,动作区分读加锁写加锁,读锁可以多个线程同时持有,写锁独占

自旋锁,等待动作不是阻塞休眠,而是循环空转尝试获取锁,适合临界区非常短的场景,不会进入内核阻塞

【常见问题】

问题 1 lock 基础动作全套里面 unlock 动作的作用是什么

回答 1 lock 基础动作全套里面 unlock 就是释放锁动作,业务操作完共享资源之后执行 unlock,把锁标记为空闲,同时唤醒等待队列里面等待锁的线程,如果缺少 unlock 动作就会出现锁泄漏。

问题 2 lock 基础动作全套里面 try lock 和普通 lock 动作有什么区别

回答 1 lock 基础动作全套里面普通 lock 拿不到锁会阻塞等待,try lock 属于非阻塞尝试加锁,拿不到锁立刻返回失败,不会挂起线程,业务可以自行决定重试或者跳过任务。

问题 3 lock 基础动作全套里面锁升级是什么意思

回答 1 lock 基础动作全套里面锁升级是细粒度锁数量过多的时候,自动升级成粗粒度锁,比如数据库大量行锁升级成表锁,目的是降低锁维护开销,但是会降低系统并发能力。

问题 4 lock 基础动作全套为什么需要死锁检测动作

回答 1 lock 基础动作全套加入死锁检测动作,是因为多个线程互相持有锁并且等待对方锁会形成死锁,系统通过死锁检测识别循环等待,牺牲部分执行单元释放锁,打破死锁,让系统可以继续运行。

【免责申明】

本文为 lock 基础动作全套通用原理讲解,不同编程语言数据库操作系统的锁实现细节参数存在差异,部分锁类型不支持锁降级,内容仅作为学习参考,不替代官方技术手册,生产环境锁设计需要结合业务高可用要求评估风险。

 

相关阅读

最新文章