概述

  锁的分类根据不同的维度可以分为以下几种:

  • 悲观锁和乐观锁
  • 共享锁(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 锁的分类的更多相关文章

  1. java 并发多线程 锁的分类概念介绍 多线程下篇(二)

    接下来对锁的概念再次进行深入的介绍 之前反复的提到锁,通常的理解就是,锁---互斥---同步---阻塞 其实这是常用的独占锁(排它锁)的概念,也是一种简单粗暴的解决方案 抗战电影中,经常出现为了阻止日 ...

  2. Java中的锁——锁的分类

    Java中有各种各样的锁,例如公平锁.乐观锁等等,这篇文章主要介绍一下各种锁的分类. 按照其性质分类 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并 ...

  3. Java中15种锁的分类综合总结

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  4. Java并发编程:Concurrent锁机制解析

    Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...

  5. 详解Java锁的升级与对比(1)——锁的分类与细节(结合部分源码)

    前言 之前只是对Java各种锁都有所认识,但没有一个统一的整理及总结,且没有对"锁升级"这一概念的加深理解,今天趁着周末好好整理下之前记过的笔记,并归纳为此博文,主要参考资源为&l ...

  6. MySQL - 锁的分类

    MySQL - 锁的分类 1. 加锁机制 乐观锁 悲观锁 2. 兼容性 共享锁 排他锁 3. 锁粒度 表锁 页锁 行锁 4. 锁模式 记录锁(record-lock) 间隙锁(gap-lock) ne ...

  7. java 锁的分类

    java中为了解决多线程并发带来的线程安全问题,引入了锁机制. 一.公平锁和非公平锁 1.公平锁:按照申请锁的顺序(FIFO队列)来获取锁. 2.非公平锁:所有线程都会竞争,获取的锁的顺序和申请顺序无 ...

  8. Java中的锁分类

    在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...

  9. Java中常见的锁分类以及对应特点

    对于 Java 锁的分类没有严格意义的规则,我们常说的分类一般都是依据锁的特性.锁的设计.锁的状态等进行归纳整理的,所以常见的分类如下: 公平锁和非公平锁:公平锁是多线程按照锁申请的顺序获取锁,非公平 ...

随机推荐

  1. 解决GitHub下载速度太慢的问题

    更改hosts文件: Windows 更改C:\Windows\System32\drivers\etc\hosts文件,在文件中追加219.76.4.4 github-cloud.s3.amazon ...

  2. 参数类型 (@Controller层)

    @RequestMapping(path = "/listPage")@SuppressWarnings("unchecked")@BussinessLog(v ...

  3. Luogu [P3622] [APIO2007]动物园

    题目链接 比较费脑子的一道题 先说题目核心思想 : 状压dp 环的处理我们先不管. 我们设 dp[j][s] 表示 到达动物 j 且 [ j , j+5) 这五个动物状态为s时 最多能使多少小朋友开心 ...

  4. AE开发之默认滚轮缩放功能反置(C#修改注册表数据)

    ArcMap默认的滚轮缩放是向下放大,向上缩小 如果想修改成向上放大,向下缩小,直接在ArcMap-Customize-ArcMap Options里, 将最下面的Mouse Wheel and Co ...

  5. CF1217B

    CF1217B 题意: 有一个有 $ x $ 个头的龙,你有 $ n $ 种方案,每种方案中包含你可以砍掉的头 $ d_i $ 和龙会生长的头 $ h_i $ 找到一种方案,使得操作数最少. 解法: ...

  6. Golang字符串处理以及文件操作

    一.整数 1.int与uint的初值比较以及其大小. 1 /* 2 #!/usr/bin/env gorun 3 @author :xxxx 4 Blog:http://www.cnblogs.com ...

  7. pwn学习日记Day17 《程序员的自我修养》读书笔记

    静态链接章小结 本章首先学习了静态链接的第一步骤,即目标文件在被链接成最终可执行文件时,输入目标文件中的各段是如何被合并到输出文件中的,链接器如何为它们分配在输出文件中的空间和地址.一旦输入段中的最终 ...

  8. 攻防世界RE1 writeup

    解题过程 将题目给出的exe文件拖入ida中,查看main函数. 分析函数的逻辑,发现用户需要输出一个字符串,存储到变量v9中.如果v9的值与v5的值相等则会打印unk_413e90中的值,否则打印a ...

  9. js中判断对象类型的几种方法

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

  10. [Phoenix] Mix 命令

    mix phx.gen.html 命令生成模板: # 其中 name 和 age 是 schema 字段名称,后面跟的是类型 # 下面这样的写法,会生成 controller 和 service 层的 ...