数据库

一分钟理解Java公平锁与非公平锁

字号+作者:益华科技来源:系统运维2025-11-05 08:29:13我要评论(0)

和朋友聊天他提到: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。b2b供应网比如下面的代码

非公平锁的 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 的“时机”把握的好,迅速“插队”完成资源抢占。

总结

上锁的过程本身也是有时间开销的,站群服务器如果操作资源的时间比上锁的时间还短建议使用非公平锁可以提高系统的吞吐率;否则就老老实实的用公平锁。

【本文是专栏作者“邢森”的原创文章,转载请联系作者本人获取授权】

戳这里,看该作者更多好文

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 解决戴尔电脑登录界面错误的方法(排查戴尔电脑登录界面错误的常见问题及解决方案)

    解决戴尔电脑登录界面错误的方法(排查戴尔电脑登录界面错误的常见问题及解决方案)

    2025-11-05 08:23

  • 电脑插入箭头教程——轻松实现个性化文档标注(使用简便的快捷方式,让你的文档更加生动有趣)

    电脑插入箭头教程——轻松实现个性化文档标注(使用简便的快捷方式,让你的文档更加生动有趣)

    2025-11-05 07:19

  • 解决电脑DNS错误,恢复网络连接的方法(电脑DNS错误导致无法上网?别担心,这里有解决办法!)

    解决电脑DNS错误,恢复网络连接的方法(电脑DNS错误导致无法上网?别担心,这里有解决办法!)

    2025-11-05 06:05

  • 小米床垫2如何改善你的睡眠质量(一款智能床垫,让你拥有舒适的睡眠体验)

    小米床垫2如何改善你的睡眠质量(一款智能床垫,让你拥有舒适的睡眠体验)

    2025-11-05 05:53

网友点评