B7. Concurrent 锁的分类
【概述】
锁的分类根据不同的维度可以分为以下几种:
- 悲观锁和乐观锁
- 共享锁(S锁,读锁)和排他锁(X锁,写锁)
- 公平锁和非公平锁
- 重入锁
- 分段锁
【悲观锁和乐观锁】
悲观锁和乐观锁是两种处理并发冲突的思路,不是指锁的具体实现。
悲观锁总是假设会发生最坏的情况,认为一个事务每次读取数据时,别的事务总会修改该数据,所以每次读取数据的时候总需要加上锁。传统的关系型数据库里有很多用到悲观锁的地方:比如行锁、表锁、读锁(共享锁)、写锁(排他锁),Java 中的 synchronized 关键字和基于AQS(java.util.concurrent.locks.AbstractQueuedSynchronizer)实现的各种锁(ReentrantLock、ReentrantReadWriteLock 等)也是使用悲观锁的思想。
乐观锁总是假设会发生最好的情况,认为一个事务每次读取数据时,别的事务不会修改该数据,所以采取是一种“无锁”的策略,但需要在更新的时候会去判断该数据有没有被修改(自旋操作)。乐观锁可以使用版本号机制和 CAS 算法(Compare-and-Swap)来实现。乐观锁适合读大于写的应用场景,可以提高并发效率,从而提高吞吐量。Java 中 java.util.concurrent.atomic 包下的原子变量类就是使用 CAS 算法实现的乐观锁。
【共享锁和排他锁】
共享锁和排他锁都会对数据进行加锁,都属于悲观锁。
共享锁(S锁)也叫读锁,如果一个事务 T 对一个数据 A 加了共享锁,则其他事务可以对数据 A 加共享锁进行读操作,但其他事务不可以对数据 A 加排他锁进行写操作;
排他锁(X锁)也叫写锁,如果一个事务 T 对一个数据 A 加了排他锁,则其他事务不可以对数据 A 加共享锁进行或者排他锁。
数据库的增删改操作默认会加排他锁,查询操作不会加锁。
Java 中的 java.util.concurrent.locks.ReentrantReadWriteLock 提供了一种读写锁的实现。
进行读操作的时候进行加锁,可以防止 “脏读” 的情况。通俗地讲,加了读锁,事务在读取数据的时候,不允许其他事务对该数据进行修改。
【公平锁和非公平锁】
所谓的 “公平” 在于是否按照线程申请锁的顺序分配锁,如果是,则为 “公平锁”,否则为 “非公平锁”。
java.util.concurrent.locks.ReentrantLock 和 java.util.concurrent.locks.ReentrantReadWriteLock 都提供了 “公平锁” 和 “非公平锁” 的构造器实现。无参构造器默认为 “非公平锁”。
synchronized 关键字提供的是一种 “非公平锁”。
实现 “公平锁” 需要使用队列实现 “FIFO”,增加了队列数据处理的开销,当队列数据较大时对性能影响较大。相对而言,“非公平锁” 具有更高的并发效率,吞吐量更大,如非必要优先选择 “非公平锁”。
【重入锁】
重入锁又叫递归锁,指的是一个获得锁后在同步块中可以进入同一把锁控制的另一代码块中,而不需要先释放锁,只需把该线程对锁的数量加1。试想一下,如果该线程尝试进入同一把锁控制的另一代码块时,需要等待锁释放,原来代码块又在等待,导致锁一直无法被释放,造成 “死锁”。java.util.concurrent.locks.ReentrantLock 、 java.util.concurrent.locks.ReentrantReadWriteLock、synchronized 关键字都是 重入锁。
【分段锁】
分段锁是一种通过细化锁粒度来获取更高并发效能的锁优化的设计思想。
分段锁的一个实现可以参考 java.util.concurrent.ConcurrentHashMap。
B7. Concurrent 锁的分类的更多相关文章
- java 并发多线程 锁的分类概念介绍 多线程下篇(二)
接下来对锁的概念再次进行深入的介绍 之前反复的提到锁,通常的理解就是,锁---互斥---同步---阻塞 其实这是常用的独占锁(排它锁)的概念,也是一种简单粗暴的解决方案 抗战电影中,经常出现为了阻止日 ...
- Java中的锁——锁的分类
Java中有各种各样的锁,例如公平锁.乐观锁等等,这篇文章主要介绍一下各种锁的分类. 按照其性质分类 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并 ...
- Java中15种锁的分类综合总结
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- Java并发编程:Concurrent锁机制解析
Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...
- 详解Java锁的升级与对比(1)——锁的分类与细节(结合部分源码)
前言 之前只是对Java各种锁都有所认识,但没有一个统一的整理及总结,且没有对"锁升级"这一概念的加深理解,今天趁着周末好好整理下之前记过的笔记,并归纳为此博文,主要参考资源为&l ...
- MySQL - 锁的分类
MySQL - 锁的分类 1. 加锁机制 乐观锁 悲观锁 2. 兼容性 共享锁 排他锁 3. 锁粒度 表锁 页锁 行锁 4. 锁模式 记录锁(record-lock) 间隙锁(gap-lock) ne ...
- java 锁的分类
java中为了解决多线程并发带来的线程安全问题,引入了锁机制. 一.公平锁和非公平锁 1.公平锁:按照申请锁的顺序(FIFO队列)来获取锁. 2.非公平锁:所有线程都会竞争,获取的锁的顺序和申请顺序无 ...
- Java中的锁分类
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...
- Java中常见的锁分类以及对应特点
对于 Java 锁的分类没有严格意义的规则,我们常说的分类一般都是依据锁的特性.锁的设计.锁的状态等进行归纳整理的,所以常见的分类如下: 公平锁和非公平锁:公平锁是多线程按照锁申请的顺序获取锁,非公平 ...
随机推荐
- PHP mmysqli_affected_rows(connection);函数
mysqli_affected_rows(); 函数返回前一次 MySQL 操作所影响的记录行数. mysqli_affected_rows(connection); connection 必需.规定 ...
- 002_89C52_Proteus_DAC0832_输出50HZ,正弦波,三角波,矩形波,锯齿波
(一)非常感谢:89C51与ad0832 输出正弦波,三角波,矩形波,锯齿波 (二)在上面的情况下进行程序的修改,实现50HZ的输出 (三)电路图 (三)输出方波 (四)输出锯齿波 (五)输出三角波 ...
- Activiti服务类- ManagementService服务类
一共含有17个方法 // 获取包含了Activiti数据库模式的{表名.行计数}项的映射.Map<String, Long> getTableCount();//获取诸如任务.执行之类的A ...
- VS2012 Update 2: 0x80040154 corrupt install when starting the debugger
使用VS2012開發console program ,发现生成32位的exe文件在別的机上不能正确运行,有文章說update1可以解決這個問題,如下 Setup.exe is not a valid ...
- MyBatisPLus入门项目实战各教程目录汇总
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 http://www.imooc.com/article/details/id/ ...
- ue/um-editor实现word图片复制
图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码 目前限chrome浏览器使用,但是项目要求需要支持所有的浏览器,包括Windows和macOS系统.没有办 ...
- 51nod 1076
* 无向图的割边将图分为不连通的两部分 * 对于是否有不想交的两条路径将s -> t 相连 * 只需判断是否处于同一部分 * Tarjan即可 #include <bits/stdc++. ...
- electron-vue搭建项目
原文链接 使用pdf.js插件与LODOP控件实现前端浏览器静默打印PDF文件 lodop官网地址:http://www.lodop.net/download.html 点击下载,文件里有使用手册 e ...
- 2019.6.24 校内测试 NOIP模拟 Day 2 分析+题解
看到Day 2的题真的想打死zay了,忒难了QwQ~ T1 江城唱晚 这明显是个求方案数的计数问题,一般的套路是DP和组合数学. 正如题目中所说,这个题是一个 math 题. ----zay ...
- 【学习笔记】OI模板整理
CSP2019前夕整理一下模板,顺便供之后使用 0. 非算法内容 0.1. 读入优化 描述: 使用getchar()实现的读入优化. 代码: inline int read() { int x=0; ...