Java 多线程高并发 0 — 锁的种类以及简要解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ocp114/article/details/82830654

在并发编程中难免会遇到各种线程控制,就需要用到锁,但是各种锁搞得眼花缭乱,下面就整理一下各种锁的简要解析,具体实现与用途就需要另外找了

  1. 自旋锁
    • 操作系统层面运用原子级汇编指令 swap 和 test_and_set 实现进程互斥,优点是响应速度快,也叫做无锁,缺点是线程不断增加时,性能会下降得较快
  2. 阻塞锁
    • 通过改变线程的状态(新建、就绪、运行、阻塞、死亡),一般是进入阻塞状态来实现线程控制,阻塞的线程不会占用 CPU 时间,不会导致 CPU 占用率过高,在竞争激烈的情况下性能要明显高于 自旋锁,但代价是在进入时间以及恢复时间都要比自旋锁略慢
    • 例如:synchronized 关键字,ReentrantLock、Object.wait()、notify()、LockSupport.park()、unpart()
  3. 可重入锁
    • 也叫做递归锁,指的是同一线程对同一个对象或者同一段代码重复获取多次锁都行,不过需要解锁多次,但是这样能尽可能避免死锁
    • 例如:ReentrantLock、synchronized
  4. 读写锁
    • 实际是一种特殊的自旋锁,里面分为读锁和写锁,读锁可以多个线程同时持有,写锁是独占的,这样能提高并发性,特别是读多写少的场景
    • 例如:ReadWriteLock
  5. 互斥锁
    • 和读写锁的读锁相对,对于某段代码或者某个对象的锁,只能一个线程持有锁,其他对象申请锁是将会被阻塞
    • 例如:synchronized
  6. 悲观锁
    • 在修改某个变量时总是认为会有其他线程对变量进行操作了,所以要先加把锁才安心
    • 例如:synchronized
  7. 乐观锁
    • 在修改某个变量时总是认为不会有其他线程对变量进行操作,所以不会加锁
    • 例如:java.util.concurrent.atomic 下面的 CAS 方式实现、版本号机制、数据库的类似于 write_condition 的机制
  8. 公平锁
    • 可以让线程获取锁的过程有一定的顺序(先申请锁,先获得锁),但是性能会下降(要处理线程排队)
    • 例如:ReentrantLock 在实例化时在构造函数给定参数 true
  9. 非公平锁:和公平锁相反
  10. 偏向锁
    • 哪个线程拥有某个对象的锁,那么对象头信息里面就会指向该线程,也就是偏向该线程,一种非常弱的锁
  11. 对象锁:该锁的作用于是一个对象
  12. 方法锁:该锁的作用于是一个方法
  13. 类锁:该锁的作用于是一个类
  14. 线程锁:作用对象是线程,可以对线程做一些线程控制方面的操作
  15. 轻量级锁
    • 较多的指在 JVM 层面的轻量级锁,用一个锁对象来嵌入到 Java 栈中,锁对象会保存被加锁对象的信息,被加锁对象的对象头也会记录锁对象的指针,详细请看,这样的操作一般不会造成线程阻塞,性能较好
    • 例如:自旋锁
  16. 重量级锁:和轻量级锁相对,会造成线程阻塞
  17. 共享锁
    • 顾名思义,一个可以共享的锁,可以让多个线程共享同一把锁,常常用在并发控制的场景
    • 例如:Semaphore
  18. 排他锁
    • 又称为写锁、独占锁,所以呀~~按照名字理解就行(认真脸)

上面只是一些概念性的知识,可能会有理解偏差,在实际中有可能同一种锁的实现由好几种锁的原理构成,例如 synchronized 是 重量级锁 也是 阻塞锁,然而不同的锁在性能和用途上有都有不同~

猜你喜欢

转载自blog.csdn.net/ocp114/article/details/82830654