简单说明乐观锁、悲观锁[共享锁、排它锁(行锁、表锁)]、死锁

一句话总结:
乐观锁and version=、悲观锁[共享锁lock in share mode、排它锁for update(索引行锁、表锁)]

Java:
独占锁reentrantLock、共享锁[写独占读共享ReentrantReadWriteLock,有限资源Semaphore、总数CountDownLatch]

括号表示子分类,英文翻译如下
re-entrant(可重入)
Semaphore(信号量)
CountDown(倒计时)
Latch(门闩shuān)

数据库锁

锁的实现

1 乐观锁

通过版本字段手动实现,适用写少的场景
写多的冲突多了不断重试反倒低性能
冲突率<20%时使用,重试次数<=3

update … 
set … version=version+1
where id=#{id} and version=#{version};

体现了对比并替换(CAS操作),用版本而不是比较某个业务值是为了避免业务值不变实际是后面变回一样的值(ABA问题)

2 悲观锁

无版本字段,其他可读不可改,分两种

2.1 共享锁

其他共享锁可以SELECT进来

SELECT …  lock in share mode;

2.2 排他锁

悲观锁(共享锁和排他锁)都不能SELECT进来

SELECT … for update;

分两种

2.2.1 行锁

使用索引

exists
SELECT … FORCE INDEX WHERE …

2.2.2 表锁

全表扫描

in

死锁

死锁条件

互斥排他
保持着排他资源又提出新资源请求
不可剥夺
环路

死锁避免

同顺序
一次性锁定
细粒度锁定(行锁)

附:线程锁的一些概念

公平锁(顺序锁)

ReentrantLock lock = new ReentrantLock(true);
lock.lock();
try {
} finally {
    lock.unlock();
}

可重入 ReEntrancy

获得锁的程序因为断网等原因离开后可以重入。同一线程可以多次获得,如JAVA的synchronized,用计数器实现进入时+1,退出时-1。

重量级锁

拿不到锁马上阻塞

自旋锁

拿不到锁先空循环一会再试然后再阻塞

自适应自旋锁

根据之前的几率调整空循环次数 JDK1.6

轻量级锁

用标记,适用于少竞争的情况

偏向锁

标记ID不释放,如果另一个发现ID不是自己就升级重量级锁,适用于一般只有一个线程访问时

锁消除

锁粗化

如JVM把循环内优化为循环外

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容