Java多线程优化之偏向锁原理分析

开发 后端
本文详细介绍了Java偏向锁的实现原理。偏向锁是Java 6引入的一项多线程优化。Java多线程优化的实现一般有轻量级锁和偏向锁两种方法。

本文来自Ken Wu's Blog,原文标题:《Java偏向锁实现原理(Biased Locking)》。

51CTO编辑推荐:Java线程专题

阅读本文的读者,需要对Java轻量级锁有一定的了解,知道lock record, mark word之类的名词。

Java偏向锁(Biased Locking)是Java 6引入的一项多线程优化。它通过消除资源无竞争情况下的同步原语,进一步提高了程序的运行性能。

轻量级锁也是一种多线程优化,它与偏向锁的区别在于,轻量级锁是通过CAS来避免进入开销较大的互斥操作,而偏向锁是在无竞争场景下完全消除同步,连CAS也不执行(CAS本身仍旧是一种操作系统同步原语,始终要在JVM与OS之间来回,有一定的开销)。

所谓的无竞争场景,举个例子,就是单线程访问带同步的资源或方法。

偏向锁实现原理

偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步。
如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会尝试消除它身上的偏向锁,将锁恢复到标准的轻量级锁。(偏向锁只能在单线程下起作用)

通过下图可以更直观的理解偏向锁:

理解偏向锁

这张图,省略了轻量级锁相关的几处步骤,将关注点更多地聚焦在偏向锁的状态变化上。
偏向模式和非偏向模式,在下面的mark word表中,主要体现在thread ID字段是否为空。

mark word表

挂起持有偏向锁的线程,这步操作类似GC的pause,但不同之处是,它只挂起持有偏向锁的线程(非当前线程)。

#T#在抢占模式的橙色区域说明中有提到,指向当前堆栈中最近的一个lock record(在轻量级锁原理一文有讲到,lock record是进入锁前会在stack上创建的一份内存空间)。
这里提到的最近的一个lock record,其实就是当前锁所在的stack frame上分配的lock record。
整个步骤是从偏向锁恢复到轻量级锁的过程。

偏向锁也会带来额外开销

在JDK6中,偏向锁是默认启用的。它提高了单线程访问同步资源的性能。
但试想一下,如果你的同步资源或代码一直都是多线程访问的,那么消除偏向锁这一步骤对你来说就是多余的。事实上,消除偏向锁的开销还是蛮大的。

所以在你非常熟悉自己的代码前提下,大可禁用偏向锁 -XX:-UseBiasedLocking 。

责任编辑:yangsai 来源: kenwublog.com
相关推荐

2018-10-25 15:55:44

Java多线程锁优化

2022-06-15 07:32:35

Lock线程Java

2023-06-09 07:59:37

多线程编程锁机制

2009-03-12 10:52:43

Java线程多线程

2017-05-31 14:03:07

Java多线程内置锁与显示锁

2017-05-08 11:46:15

Java多线程

2021-07-30 19:44:51

AndroidJava线程

2020-01-16 14:59:32

Java锁优化CAS

2011-06-13 10:41:17

JAVA

2017-11-17 15:57:09

Java多线程并发模型

2023-10-08 09:34:11

Java编程

2011-04-14 13:27:53

Synchronize多线程

2013-05-23 15:59:00

线程池

2022-05-26 08:31:41

线程Java线程与进程

2024-03-18 12:21:28

Java轻量级锁重量级锁

2012-03-30 11:16:29

JavaVisualVM

2022-05-27 08:16:37

Thread类Runnable接口

2020-08-26 08:59:58

Linux线程互斥锁

2019-12-19 09:23:45

Java多线程数据

2023-06-07 13:49:00

多线程编程C#
点赞
收藏

51CTO技术栈公众号