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 锁的分类没有严格意义的规则,我们常说的分类一般都是依据锁的特性.锁的设计.锁的状态等进行归纳整理的,所以常见的分类如下: 公平锁和非公平锁:公平锁是多线程按照锁申请的顺序获取锁,非公平 ...
随机推荐
- fputcsv
1.a是從結尾添加,w是從頭添加,不知爲什麽 這樣寫最後一行會是錯的,似乎不會自動添加換行符,只有在最後以行寫上"\r\n",才會正確. $fp = sugar_fopen('fi ...
- JXOJ 9.7 NOIP 放松模拟赛 总结
比赛链接 T1 数数 题意:有a个红球,b个黄球,c个蓝球,d个绿球排成一列,求任意相邻不同色的排列的数目 1 <= a , b, c, d <= 30 答案对1e9 + 7 取膜 用 ...
- CodeForces - 999B Reversing Encryption
B - Reversing Encryption A string s of length n can be encrypted by the following algorithm: iterate ...
- maven项目无法查看类库的源码
一个Maven项目有两种类库,分别是JRE System Libaray和Maven Dependencies. JRE System Libaray 一般有两种方法指定. 1.由pom.xml中的m ...
- Elasticsearch的Search详解
介绍 ES不是新技术,是将全文检索和数据分析.分布式整合到一起. 基于lucene开发,提供简单的restful api接口.java api接口.其他语言开发接口等. 实现了分布式的搜索引擎和分析引 ...
- AngularJS开发中常用的写法,如:获取URL参数、路由跳转、$http、获取元素等
控制器,带状态 app.controller('editCtrl', ['$http', '$location', '$rootScope', '$scope', '$state', '$stateP ...
- Windows使用Vagrant&VirtualBox搭建虚拟开发环境
Vagrant 是一款用来构建虚拟开发环境的工具 , 我们可以通过 Vagrant 封装一个 Linux 的开发环境 , 分发给团队成员 ; 成员可以在自己喜欢的桌面系统 Mac/Windows/Li ...
- 移动端—— 兼容PC端,移动端的点击事件
移动设备上不支持鼠标事件,好在webkit内核的移动浏览器支持 touch 事件,所以触摸事件是移动应用中所必须的.touchstart.touchmove.touchend事件可以类比于moused ...
- Android-Handler消息机制实现原理)(转)
Android-Handler消息机制实现原理 一.消息机制流程简介 在应用启动的时候,会执行程序的入口函数main(),main()里面会创建一个Looper对象,然后通过这个Looper对象开 ...
- java泛型中特殊符号的含义
java泛型中的标记符含义: E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Number ...