java 偏向锁_Java并发之彻底搞懂偏向锁升级为轻量级锁
网上有许多讲偏向锁,轻量级锁的文章,但对偏向锁如何升级讲的不够明白,有些文章还相互矛盾,经过对jvm源码(biasedLocking.cpp)的仔细分析和追踪,基本升级过程有了一个清晰的过程,现将升级流程阐述如下:
因为偏向锁,锁住对象时,会写入对象头相应的标识,我们先把对象头(官方叫法为:Mark Word)的图示如下(借用了网友的图片):
通过上面的图片,我们可以知道,对象处于偏向锁时,mark word中的偏向锁标记为1,锁标志位为01;下面是分析过jvm源码(biasedLocking.cpp)解析的偏向锁升级流程(忽略一些细节),示例中:线程1当前拥有偏向锁对象,线程2是需要竞争到偏向锁。
线程2来竞争锁对象;
判断当前对象头是否是偏向锁;
判断拥有偏向锁的线程1是否还存在;
线程1不存在,直接设置偏向锁标识为0(线程1执行完毕后,不会主动去释放偏向锁);
使用cas替换偏向锁线程ID为线程2,锁不升级,仍为偏向锁;
线程1仍然存在,暂停线程1;
设置锁标志位为00(变为轻量级锁),偏向锁为0;
从线程1的空闲monitor record中读取一条,放至线程1的当前monitor record中;
更新mark word,将mark word指向线程1中monitor record的指针;
继续执行线程1的代码;
锁升级为轻量级锁;
线程2自旋来获取锁对象;
上面仍有一个问题,即如何判断线程1已经不存在了?
仍然是分析完jvm源码(thread.cpp)后,得到的如下结论:
(1) 线程执行start时,会将自己写入一个thread_list中,这是一个linked结构,有pre和next节点;
对应源码位置:
void Threads::add(JavaThread* p, bool force_daemon) {
// The threads lock must be owned at this point
assert_locked_or_safepoint(Threads_lock);
// See the comment for this method in thread.hpp for its purpose and
// why it is called here.
p->initialize_queues();
p->set_next(_thread_list);
_thread_list = p;
_number_of_threads++;
oop threadObj = p->threadObj();
bool daemon = true;
// Bootstrapping problem: threadObj can be null for initial
// JavaThread (or for threads attached via JNI)
if ((!force_daemon) && (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj))) {
_number_of_non_daemon_threads++;
daemon = false;
}
p->set_safepoint_visible(true);
ThreadService::add_thread(p, daemon);
// Possible GC point.
Events::log(p, "Thread added: " INTPTR_FORMAT, p);
}
(2)线程执行完后,会将自己从thread list中清理掉(源码位置: Threads::remove(this));
因此只需判断thread list中是否存在线程1即可,判断源代码(位于biasedLocking.cpp中 )如下:
bool thread_is_alive = false;
if (requesting_thread == biased_thread) {
thread_is_alive = true;
} else {
for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
if (cur_thread == biased_thread) {
thread_is_alive = true;
break;
}
}
java 偏向锁_Java并发之彻底搞懂偏向锁升级为轻量级锁相关推荐
- java build 模式_Java Builder 模式,你搞懂了么?
前言:最近闲来无事的时候想着看看一些平常用的三方库源码,没想到看了之后才知道直接撸源码好伤身体,一般设计优秀的开源库都会涉及很多的设计模式,就比如 android 开发使用频繁的 okHttp 打开源 ...
- synchronized锁升级之轻量级锁
目录 一.什么是轻量级锁? 二.为什么引入轻量级锁? 三.轻量级锁的升级时机 四.轻量级锁的演示 五.轻量级锁的原理 六.轻量级锁升级为重量级锁的流程 七.轻量级锁的优缺点 一.什么是轻量级锁? 轻量 ...
- 自旋锁 轻量锁_Java知识进阶-程序员升往架构师必经之路-自旋锁-知识铺
知识铺: 致力于打造轻知识点,持续更新每次的知识点较少,阅读不累.不占太多时间,不停的来唤醒你记忆深处的知识点. 一. 锁类型 1.1 乐观锁 Java中CAS操作,就是一种乐观锁,前文也讲过了详细的 ...
- java中JAO_JVM内部细节之一:synchronized关键字及实现细节(轻量级锁Lightweight Locking)...
在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作.然而在Java中除了提供Lock API外还在语法层面上提供了synchronized关键字来实现互斥同步 ...
- 面试让HR都能听懂的MySQL锁机制,欢声笑语中搞懂MySQL锁
腾讯云数据库负责人林晓斌说过:"我们面试MySQL同事时只考察两点,索引和锁".言简意赅,MySQL锁的重要性不言而喻. 本文通过同事"侨总"的一场面试,带你通 ...
- 一文搞懂Oracle 0 至 6 级锁(附案例详解)
11g Concepts中摘录的锁的信息 Table Locks (TM) A table lock, also called a TM lock, is acquired by a transact ...
- mysql某个表被行锁了_一文搞懂MySQL行锁、表锁、间隙锁详解
准备工作 创建表 tb_innodb_lock drop table if exists test_innodb_lock; CREATE TABLE test_innodb_lock ( a INT ...
- java 原型图_一张图搞懂原型、原型对象、原型链
基本概念 在javascript中,函数可以有属性. 每个函数都有一个特殊的属性叫作原型(prototype) 每个对象拥有一个原型对象 [[Prototype]] / __proto__ / Obj ...
- java cas原理_Java并发之原子变量及CAS算法-上篇
Java并发之原子变量及CAS算法-上篇 编辑 概述 本文主要讲在Java并发编程的时候,如果保证变量的原子性,在JDK提供的类中是怎么保证变量原子性的呢?.对应Java中的包是:java.uti ...
最新文章
- 查询提升200倍,ClickHouse你值得拥有!
- android adb 控制手机,adb 控制手机动作
- JAVA复习5(集合——拓展——单向链表)
- EXT.NET复杂布局(四)——系统首页设计(上)
- C语言版数据结构及算法_快速排序
- 声明 static 变量注意事项
- 使用anaconda切换Python环境使用spyder
- A browser for WinCE/Windows base WebKit. (zz)
- linux设置挂载服务端防火墙_「rpcbind」Linux下nfs+rpcbind实现服务器之间的文件共享(mount 挂载) - seo实验室...
- 小米手机的miui10 连接电脑。本地播放器推荐。
- Linux安装lrzsz
- Java毕业设计项目【畅购商城】
- 应广单片机开发调试应注意的问题
- JQuery插件Validation的使用-遁地龙卷风
- 电音(3)音色分类和调制
- 信息安全数学基础(一):同余
- 要闻君说:印度公司要在京沪建立数据中心;超 10 万个 GitHub 仓库可泄漏 API 令牌及密钥...
- 解决mysql一段时间后不能启动
- CHAPTER 9 Web服务与应用(一)
- 物理机服务器cpu性能排行榜,g务器cpu性能排行_CPU天梯图2019年7月份新版——CPU性能排行天梯图...