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自旋来获取锁对象;
// The threads lock must be owned at this pointassert_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);
}
for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
Java并发之彻底搞懂偏向锁升级为轻量级锁的更多相关文章
- Java并发之锁升级:无锁->偏向锁->轻量级锁->重量级锁
Java并发之锁升级:无锁->偏向锁->轻量级锁->重量级锁 对象头markword 在lock_bits为01的大前提下,只有当是否偏向锁位值为1的时候,才表明当前对象处于偏向锁定 ...
- java 偏向锁怎么升级为轻量级锁
因为偏向锁,锁住对象时,会写入对象头相应的标识,我们先把对象头(官方叫法为:Mark Word)的图示如下(借用了网友的图片): 通过上面的图片,我们可以知道,对象处于偏向锁时,mark word中的 ...
- MySQL 避免行锁升级为表锁——使用高效的索引
文章目录 普通索引 属性值重复率高 属性值重复率低 小结 众所周知,MySQL 的 InnoDB 存储引擎支持事务,支持行级锁(innodb的行锁是通过给索引项加锁实现的).得益于这些特性,数据库支持 ...
- 每个java初学者都应该搞懂的问题
对于这个系列里的问题,每个学JAVA的人都应该搞懂.当然,如果只是学JAVA玩玩就无所谓了.如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列.内容均来自于CSDN的经典老贴. ...
- 五分钟学Java:一篇文章搞懂spring和springMVC
原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 什么是Spring,为什么你要学习spring? 你第一次接触spring框架是在什么时候?相信很多人和我一样,第一次了 ...
- Java Builder 模式,你搞懂了么?
加油.png 前言:最近闲来无事的时候想着看看一些平常用的三方库源码,没想到看了之后才知道直接撸源码好伤身体,一般设计优秀的开源库都会涉及很多的设计模式,就比如 android 开发使用频繁的 okH ...
- Java基础-一文搞懂位运算
在日常的Java开发中,位运算使用的不多,使用的更多的是算数运算(+.-.*./.%).关系运算(<.>.<=.>=.==.!=)和逻辑运算(&&.||.!), ...
- JAVA初级必须要搞懂的事项(希望对新手有所帮助)
1 安装JDK=> (1,下载JDK,安装,一般目录为C:\Program Files\Java中:2,通过Dos命令测试JDK是否安装=>java –version命令查看 ...
- 线程池 | Java多线程,彻底搞懂线程池
熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了. 最近看了一些相关文章,并亲自研究了一下源码,发现有些文章还是有些问题的,所以我也总结了 ...
随机推荐
- leetcode mock interview-two sum II
package com.company; import java.util.LinkedList; import java.util.List; public class Main { public ...
- MSSQL 触发器 暂停 和 启动
开启关闭触发器 禁用: ALTER TABLE member DISABLE TRIGGER trig1 GO 恢复: ALTER TABLE member ENABLE TRIGGER trig1 ...
- [Python爬虫] 之五:Selenium 处理滚动条
selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了. 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的.这时候需要借助滚动条来拖 ...
- php 单进程SAPI生命周期
php的生命周期3.1 STARTUP 1.初始化引擎和核心组件. 2.解析php.ini. 3.初始化静态构建的模块(MINIT). 4.初始化共享模块(MINIT).3.2 ...
- Microsoft Office Word 2007 文档结构图突然变小的解决办法
前记: 一个word文档不知道修改了什么,突然发现文档结构图显示的文字变得非常的小了. 用ctrl+鼠标滚轮只能放大或是缩小行间距,对文字没有什么变化. 解决办法: 1.打开文档结构图 点击视图,勾选 ...
- 【React】初识React
React是什么 React是如今(2015年)最热门的前端技术. 在React中.一切皆组件. A JavaScript library for building user interfaces R ...
- 【SSH三大框架】Hibernate基础第五篇:利用Hibernate完毕简单的CRUD操作
这里利用Hibernate操作数据库完毕简单的CRUD操作. 首先,我们须要先写一个javabean: package cn.itcast.domain; import java.util.Date; ...
- 一致性哈希算法(Consistent Hashing) .
应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...
- 随机数的生成:给定1-n的随机数生成器randn(),生成1-m的随机数
1.当m < n时比较简单: 只当randn()生成的数落在1-m上时,就输出,否则继续生成: 2.当m > n时就比较麻烦一点, 基本思路还是和第一种情况是一样的,问题是怎样才能利用ra ...
- js&jquery获取指定table指定行里面的内容
js&jquery获取指定table指定行里面的内容 CreateTime--2018年5月18日11:46:04 Author:Marydon 1.展示 代码展示 <table s ...