Hotspot锁实现1理解Java并发(4):Hotspot并发实现浅析并发编程理解并发刨根问底ContentsHead word ............................................................................................. 1Hotspot锁实现 ........................................................................................ 1轻量级加锁过程()偏向锁()学习一下中的锁实现。Head word中对象头包含两部分信息,一个是,存储同步、等信息;另一部分是存该对象所属的类型的指针:Hotspot锁实现轻量级加锁过程(thin lock)对于一个未锁定的对象,如果不允许偏向,那么当线程尝试给这个对象加锁的时候,首先尝试使用轻量级锁定,步骤如下:首先在当前线程的桢栈中创建一个信息,保存对象的,然后尝试通过把这个的地址设置到对象的中如果成功,那么当前线程成功获取到锁,这时候最后两位是,表示对象被轻量级锁定如果失败,这时候首先需要判断一下当前线程是否已经持有锁(存在当前线程递归获取锁的场景;但比较的时候,比较的条件是按照对象未锁定的场景去比较的,所以即使对象已经被轻量级锁定了,在之前根本没有去判断),如果是则表明当前线程已经取得锁,可以继续执行如果不是,那么说明有两个线程同时尝试锁定一个对象,这时候需要膨胀为重量级锁// bytecodeInterpreter.cpp if (!success) { markOop displaced = rcvr->mark()->set_unlocked(); mon->lock()->set_displaced_header(displaced); if (Atomic:: (mon, rcvr->mark_addr(), displaced) != displaced) { // Is it simple recursive case? if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { mon->lock()->set_displaced_header(NULL); } else { CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); } } }而当线程运行完成之后,还需要把对象的还原回去: Hotspot锁实现2从线程的栈中获取原来的,尝试使用设置到对象上如果成功,那么不需要做其他事情如果失败,表明已经膨胀为重量级锁了,需要通知到等待线程对于同一个线程递归锁定的场景,如果上一步失败发现已经被自己持有锁,这个时候在栈上的中设置为,个人理解是如果设置为那么在解锁的时候,可以控制不采用恢复对象,而是等到第一个操作对应的操作的时候去恢复。偏向锁(Store-Free Biased Locking)轻量级加锁解决的问题就是,多个线程交替地去获取锁,但实际没有并发争用。在实际的软件中,还有许多场景是,一个对象在生命周期内由始至终只有一个线程会去锁定,那么,在这这种情况下是否可以避免反复的操作,而是直接偏向让原来持有锁的线程获取锁呢?对象初始化的时候的有会有一个是否允许偏向的标志位:如果该类可以使用偏向锁,则对象包含(初始化位),表示允许偏向如果该类不可以使用偏向锁,则对象包含一个,被设置位表示不允许偏向那么,在尝试加锁的过程中,如果发现允许偏向,则步骤如下:尝试通过,将当前线程、等替换到对象头中,这是唯一的一次操作,称之为当线程持有对象的偏向锁之后,后续该线程的加锁和解锁无需额外的操作或者更新对象头而当一个线程尝试对一个偏向其他线程的对象加锁的时候,需要撤销偏向锁,并把现场恢复成好像是通过锁住这个对象一样。这时候进行的步骤如下:停止偏向锁持有线程到安全点遍历偏向锁的持有线程的栈,调整为的模式;并把最开始的设置到对象的中恢复线程,按照的方式执行(包括膨胀机制) Hotspot锁实现3