您现在的位置是:亿华云 > 系统运维
一分钟理解Java公平锁与非公平锁
亿华云2025-10-09 03:29:12【系统运维】5人已围观
简介和朋友聊天他提到:ReentrantLock 的构造函数可以传递一个 bool 数据,true 时构造的是“公平锁”、false 时构造的是“非公平锁”。我的印象中锁是不区分类型的,所以认为这应该是
和朋友聊天他提到:ReentrantLock 的分钟构造函数可以传递一个 bool 数据,true 时构造的理解是“公平锁”、false 时构造的公平公平是“非公平锁”。
我的锁非锁印象中锁是不区分类型的,所以认为这应该是分钟 Java 发明的概念,于是理解就恶补了一下。
锁的公平公平底层实现
无论什么语言在操作系统层面锁的操作都会变成系统调用(System Call),以 Linux 为例,锁非锁就是分钟 futex 函数,可以把它理解为两个函数: futex_wait(s),理解对变量 s 加锁;futex_wake(s)释放 s 上的公平公平锁,唤醒其他线程。锁非锁
如果你熟悉操作系统原理其实就是分钟 P/V 操作。
Java 公平锁和非公平锁
公平锁的理解 lock 操作是调用futex_wait,unlock 操作是公平公平调用futex_wake。源码库比如下面的代码
非公平锁的 lock/unlock 操作会先做一次 CAS 操作然后再调用 futex_wait、futex_wake。比如下面的代码
在上锁之前增加了一个 CAS 原子操作,它接受三个变量可以把它理解为下面的逻辑:
***个参数的值和第二个参数不相等则返回 0 表示操作失败否则更新为新的值。这个函数不是由代码实现的而是 CPU 提供的一个指令,比如 Intel 的叫 cmpxchg;高级语言进行了封装,比如 Java 的 Atomic 变量。
为什么
明白了原理再来提问为什么,在上锁之前先通过 CAS 修改一个变量表示“我要上锁”了看似很冗余的操作,其实它是一次自旋,如果资源很快被使用完可以提高系统的吞吐率。考虑下面的场景
上锁之前的时间是 t1,上锁之后是 t2(使用资源),释放锁是云服务器 t3。
现在有两个线程,处于 t1 状态,其中 A 线程先抢到资源处于 t2 ;B 线程也会尝试 lock,与此同时 t2 释放了,而 lock 动作也执行成功了 B 被挂起;系统继续执行 A 释放成功唤醒 B 继续执行。
上述过程中 B 只要再多等待“一丢丢”就不用被挂起,直接获得资源继续执行。非公平锁的 CAS 操作就是为了增加一丢丢时间。
采用非公平锁,如果系统中有 3 个线程执行,A 抢到资源,C 没有抢到处于挂起状态,此时 B 尝试 CAS 操作,而 A 刚好释放掉资源还没有来得及唤醒 C,那么 B 会先抢到资源,在 C 之前执行。这就是“非公平”的来历,虽然 C 老老实实的等待了很长时间,但是 B 的“时机”把握的好,迅速“插队”完成资源抢占。
总结
上锁的过程本身也是有时间开销的,源码下载如果操作资源的时间比上锁的时间还短建议使用非公平锁可以提高系统的吞吐率;否则就老老实实的用公平锁。
【本文是专栏作者“邢森”的原创文章,转载请联系作者本人获取授权】
戳这里,看该作者更多好文
很赞哦!(16768)
相关文章
- 3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。
- 怎么做好域名投资?新手必须要注意这些
- 域名解析要知道哪些?新手要如何完成动态域名解析?
- 看SEO站长如何选域名?有什么好的方法?
- 如果你的潜在终端必须是这个米(域名),那么潜在终端并不多,也没有硬通货,那么你的域名应该在终端有兴趣购买时出售。否则,你可能得自己留着吃。
- 为什么现在中文域名逐步起来了?中文域名有什么趋势?
- 什么域名报价和问价?域名报价要了解什么?
- 域名解析要知道哪些?新手要如何完成动态域名解析?
- 4、域名传输时,取决于域名原始用户的邮箱是否有效,以及他是否将密码发送到此邮箱。
- 新手对域名建站是如何理解的?该怎么进行建站?