作为一名 Java 面试者你应该知道的,Java 多进程从头讲到尾
1 什么是自旋锁和互斥锁?
由于 CLH 锁是一种自旋锁,那么我们先来看看自旋锁是什么?
自旋锁说白了也是一种互斥锁,只不过没有抢到锁的线程会一直自旋等待锁的释放,处于 busy-waiting 的状态,此时等待锁的线程不会进入休眠状态,而是一直忙等待浪费 CPU 周期。因此自旋锁适用于锁占用时间短的场合。
这里谈到了自旋锁,那么我们也顺便说下互斥锁。这里的互斥锁说的是传统意义的互斥锁,就是多个线程并发竞争锁的时候,没有抢到锁的线程会进入休眠状态即 sleep-waiting,当锁被释放的时候,处于休眠状态的一个线程会再次获取到锁。缺点就是这一些列过程需要线程切换,需要执行很多 CPU 指令,同样需要时间。如果 CPU 执行线程切换的时间比锁占用的时间还长,那么可能还不如使用自旋锁。因此互斥锁适用于锁占用时间长的场合。
2 什么是 CLH 锁?
CLH 锁其实就是一种是基于逻辑队列非线程饥饿的一种自旋公平锁,由于是 Craig、Landin 和 Hagersten 三位大佬的发明,因此命名为 CLH 锁。
CLH 锁原理如下:
首先有一个尾节点指针,通过这个尾结点指针来构建等待线程的逻辑队列,因此能确保线程线程先到先服务的公平性,因此尾指针可以说是构建逻辑队列的桥梁;此外这个尾节点指针是原子引用类型,避免了多线程并发操作的线程安全性问题;
通过等待锁的每个线程在自己的某个变量上自旋等待,这个变量将由前一个线程写入。由于某个线程获取锁操作时总是通过尾节点指针获取到前一线程写入的变量,而尾节点指针又是原子引用类型,因此确保了这个变量获取出来总是线程安全的。
这么说肯定很抽象,有些小伙伴可能不理解,没关系,我们心中可以有个概念即可,后面我们会一步一图来彻彻底底把 CLH 锁弄明白。
3 为什么要学习 CLH 锁?
好了,前面我们对 CLH 锁有了一个概念后,那么我们为什么要学习 CLH 锁呢?
研究过 AQS 源码的小伙伴们应该知道,AQS 是 JUC 的核心,而 CLH 锁又是 AQS 的基础,说核心也不为过,因为 AQS 就是用了变种的 CLH 锁。如果要学好 Java 并发编程,那么必定要学好 JUC;学好 JUC,必定要先学好 AQS;学好 AQS,那么必定先学好 CLH。因此,这就是我们为什么要学习 CLH 锁的原因。
总结
面试前的“练手”还是很重要的,所以开始面试之前一定要准备好啊,不然也是耽搁面试官和自己的时间。
我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
评论