概述

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

  • 悲观锁和乐观锁
  • 共享锁(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. 002_linux之点灯(汇编深度解析)

    1.      开发板采用韦山东的开发板 2.      芯片CPU三星S3C2440A 3.  控制引脚:GPF4 4.  linux操作系统 5. 芯片手册下载地址:https://eyun.ba ...

  2. background-size值为cover和值为100%的区别

    background-size:100% 100%;---按容器比例撑满,图片变形: background-size:cover;---把背景图片放大到适合元素容器的尺寸,图片比例不变. IE8及以下 ...

  3. 【概率论】3-3:累积分布函数(Cumulative Distribution Function)

    title: [概率论]3-3:累积分布函数(Cumulative Distribution Function) categories: Mathematic Probability keywords ...

  4. Dubbo——配置

    一.配置原则 JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口. XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的 ...

  5. MySQL数据分析-(15)表补充:存储引擎

    大家好,我是jacky,很高兴继续跟大家分享<MySQL数据分析实战>,今天跟大家分享的主题是表补充之存储引擎: 我们之前学了跟表结构相关的一些操作,那我们看一下创建表的SQL模型: 在我 ...

  6. c++ 容器切片反转次序(拷贝到新容器)

    code: // rotate_copy algorithm example #include <iostream> // cout #include <algorithm> ...

  7. UVALive 4726 Average ——(斜率优化DP)

    这是第一次写斜率优化DP= =.具体的做法参照周源论文<浅谈数形结合思想在信息学竞赛中的应用>.这里仅提供一下AC的代码. 有两点值得注意:1.我这个队列的front和back都是闭区间的 ...

  8. python异常链

    习惯使用java开发,在java开发里有异常链概念和重新抛出异常,在python是怎么实现的呢? 1.异常链 1.1.java实现 public static void test1() throws ...

  9. RuntimeException异常处理汇总

    Java中所有异常的父类是Throwable类,在Throwable类下有两大子类: 一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeat ...

  10. JAVA基础知识|类设计技巧

    1.一定要保证数据私有 2.一定要对数据初始化 3.不要再类中使用过多的基本类型 4.不是所有的域都需要独立的域访问器和域更改器 5.将职责过多的类进行分解 6.类名和方法名要能够体现它们的职责 7. ...