轻量级锁也是一种多线程优化,它与偏向锁的区别在于,轻量级锁是通过CAS来避免进入开销较大的互斥操作,而偏向锁是在无竞争场景下完全消除同步,连CAS也不执行(CAS本身仍旧是一种操作系统同步原语,始终要在JVM与OS之间来回,有一定的开销)。
所谓的无竞争场景,举个例子,就是单线程访问带同步的资源或方法。
偏向锁实现原理
偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步。
如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会尝试消除它身上的偏向锁,将锁恢复到标准的轻量级锁。(偏向锁只能在单线程下起作用)
通过下图可以更直观的理解偏向锁:
这张图,省略了轻量级锁相关的几处步骤,将关注点更多地聚焦在偏向锁的状态变化上。
偏向模式和非偏向模式 ,在下面的mark word表中,主要体现在thread ID字段是否为空。
挂起持有偏向锁的线程 ,这步操作类似GC的pause,但不同之处是,它只挂起持有偏向锁的线程(非当前线程)。
在抢占模式的橙色区域说明中有提到,指向当前堆栈中最近的一个lock record(在轻量级锁原理一文有讲到,lock record是进入锁前会在stack上创建的一份内存空间)。
这里提到的最近的一个lock record,其实就是当前锁所在的stack frame上分配的lock record。
整个步骤是从偏向锁恢复到轻量级锁的过程。
偏向锁也会带来额外开销
在JDK6中,偏向锁是默认启用的。它提高了单线程访问同步资源的性能。
但试想一下,如果你的同步资源或代码一直都是多线程访问的,那么消除偏向锁这一步骤对你来说就是多余的。事实上,消除偏向锁的开销还是蛮大的。
所以在你非常熟悉自己的代码前提下,大可禁用偏向锁 -XX:-UseBiasedLocking 。
分享到:
相关推荐
总的来说,Java的`synchronized`通过对象头的Mark Word和Monitor对象实现了线程安全的同步机制,同时引入了偏向锁、轻量级锁和自旋锁等优化手段,以平衡性能和线程安全性。理解这些锁的工作原理对于编写高性能的并发...
很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁,...
Java并发机制的底层实现原理涉及到多个方面,包括了本地内存与线程安全的问题、volatile关键字的使用、synchronized关键字的原理以及Java并发在处理器层面是如何实现的。通过这些机制,Java能够有效地管理多线程环境...
在实际编程中,可以利用Java提供的`synchronized`关键字或`java.util.concurrent.locks`包中的`ReentrantLock`等工具类来实现锁。理解并熟练运用偏向锁、轻量级锁和重量级锁的原理,有助于编写出更加高效且线程安全...
5. 重量级锁:重量级锁是 synchronized 锁的一种实现方式,使用互斥量来实现锁机制。 二、ReentrantLock 锁 1. 锁的原理:ReentrantLock 锁是基于 AQS(AbstractQueuedSynchronizer)机制来实现的。 2. 锁的分类:...
Monitor,也就是监视器,是基于Java虚拟机(JVM)实现的一种锁机制,它确保同一时刻只有一个线程能够执行特定的同步代码。 在JDK1.6之前,`synchronized`被视为重量级锁,因为它涉及到操作系统层面的互斥量(Mutex...
Java锁的升级策略是指Java语言中锁机制的四种状态:无锁状态、偏向锁、轻量级锁、重量级锁。这些锁状态都是专门针对Synchronized关键字的,是为了提高获得锁和释放锁的效率。 首先,无锁状态是指没有任何锁的状态。...
java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
在Java中,ReentrantReadWriteLock类是读写锁的实现,它包含两个锁:读锁(共享锁)和写锁(独占锁)。读锁可以被多个线程同时持有,而写锁是独占的,当写锁被占用时,其他线程既不能获取读锁也不能获取写锁。 5. ...
在Java虚拟机(JVM)中,当一个线程访问同步块并获取锁时,如果发现对象头的Mark Word标记为偏向锁状态(101),且锁对象未被其他线程持有,JVM就会将该线程的线程ID记录在Mark Word中,并将锁状态保持为偏向锁。...
为解决这个问题,Java 1.6 版本中引入了锁升级机制,包括偏向锁、轻量级锁和重量级锁三个阶段。偏向锁是指直接把当前锁偏向于某个线程,通过 CAS 修改偏向锁标记,这种锁适合同一个线程多次去申请同一个锁资源并且...
Java 并发编程 Synchronized 关键字实现原理 Synchronized 关键字是 Java 并发编程中最基本的同步机制,它可以保证线程安全,包括原子性、可见性和有序性。Synchronized 关键字可以修饰方法或代码块,使得在同一...
除了使用 `synchronized` 关键字外,我们还可以自己实现锁来实现同步。下面将通过一个简单的例子来展示如何自定义锁。 ```java public class ShadowLock { // 1. 标识线程是否在同步块内,是否已经成功上锁 ...
Java虚拟机在某些情况下会自动进行锁升级,即从偏向锁升级到轻量级锁,再升级到重量级锁。这种机制旨在减少锁的竞争,提高程序的并发性能。 ##### 2. 死锁避免 为了避免死锁的发生,Java提供了一些工具和技术,如`...
Java对象头是实现锁的关键部分。在Hotspot虚拟机中,对象头包含两部分:Mark Word和Klass Pointer。Mark Word存储对象的运行时数据,如哈希码、GC年龄、锁状态标志等。锁状态标志用于标识当前对象锁的状态,包括无锁...
Java中,`java.util.concurrent.atomic`包下的原子变量类如AtomicInteger、AtomicLong等利用CAS(Compare and Swap)算法实现了乐观锁。 - **悲观锁**假设并发环境下数据频繁被修改,因此在读取时就会上锁,确保...
Monitor是一种数据结构,用于实现锁机制。在Java对象头中,包含了一个指向Monitor的指针,当线程尝试进入同步代码块或方法时,如果锁未被持有,线程会被阻塞并等待;当锁被释放时,等待的线程会尝试重新获取锁并继续...
Java多线程锁机制相关原理实例解析 Java多线程锁机制是指在Java编程语言中,用于解决多线程并发访问共享资源的机制。该机制主要通过锁机制来实现线程同步,确保多线程之间的安全访问共享资源。 锁机制是Java多线程...
在 JAVA 中,锁机制分为四个状态:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。 在 JAVA 中,使用 Synchronized 关键字可以实现线程同步,即加锁。加锁可以使一段代码在同一时间只有一个线程可以访问,在...