盘一盘 synchronized (一)—— 从打印Java对象头说起
Java对象头的组成
|--------------------------------------------------------------------------------------------------------------|
| Object Header (128 bits) |
|--------------------------------------------------------------------------------------------------------------|
| Mark Word (64 bits) | Klass Word (64 bits) |
|--------------------------------------------------------------------------------------------------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 | OOP to metadata object | 无锁
|----------------------------------------------------------------------|--------|------------------------------|
| thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | lock:2 | OOP to metadata object | 偏向锁
|----------------------------------------------------------------------|--------|------------------------------|
| ptr_to_lock_record:62 | lock:2 | OOP to metadata object | 轻量锁
|----------------------------------------------------------------------|--------|------------------------------|
| ptr_to_heavyweight_monitor:62 | lock:2 | OOP to metadata object | 重量锁
|----------------------------------------------------------------------|--------|------------------------------|
| | lock:2 | OOP to metadata object | GC
|--------------------------------------------------------------------------------------------------------------|

使用JOL工具类,打印对象头
使用maven的方式,添加jol依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.8</version>
</dependency>
创建一个对象A
public class A {
boolean flag = false;
}
使用jol工具类输出A对象的对象头
public static void main(String[] args){
A a = new A();
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
看看输出结果
偏向锁
public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
A a = new A();
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
输出结果


public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
A a = new A();
synchronized (a){
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
}
此时对象a,对象头内容有了明显的变化,当前偏向锁偏向主线程。
轻量级锁
public static void main(String[] args) throws Exception {
Thread.sleep(5000);
A a = new A(); Thread thread1= new Thread(){
@Override
public void run() {
synchronized (a){
System.out.println("thread1 locking");
out.println(ClassLayout.parseInstance(a).toPrintable()); //偏向锁
}
}
};
thread1.start();
thread1.join();
Thread.sleep(10000); synchronized (a){
out.println("main locking");
out.println(ClassLayout.parseInstance(a).toPrintable());//轻量锁
}
}
thread1中依旧输出偏向锁,主线程获取对象A时,thread1虽然已经退出同步代码块,但主线程和thread1仍然为锁的交替竞争关系。故此时主线程输出结果为轻量级锁。
重量级锁
public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
A a = new A();
Thread thread1 = new Thread(){
@Override
public void run() {
synchronized (a){
System.out.println("thread1 locking");
System.out.println(ClassLayout.parseInstance(a).toPrintable());
try {
//让线程晚点儿死亡,造成锁的竞争
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
synchronized (a){
System.out.println("thread2 locking");
System.out.println(ClassLayout.parseInstance(a).toPrintable());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread1.start();
thread2.start();
}
thread1 和 thread2 同时竞争对象a,此时输出结果为重量级锁
盘一盘 synchronized (一)—— 从打印Java对象头说起的更多相关文章
- 并发王者课-青铜5:一探究竟-如何从synchronized理解Java对象头中的锁
在前面的文章<青铜4:synchronized用法初体验>中,我们已经提到锁的概念,并指出synchronized是锁机制的一种实现.可是,这么说未免太过抽象,你可能无法直观地理解锁究竟是 ...
- 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现
一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...
- java对象头信息和三种锁的性能对比
java头的信息分析 首先为什么我要去研究java的对象头呢? 这里截取一张hotspot的源码当中的注释 这张图换成可读的表格如下 |-------------------------------- ...
- JAVA对象头详解(含32位虚拟机与64位虚拟机)
为什么要学习Java对象头 学习Java对象头主要是为了解synchronized底层原理,synchronized锁升级过程,Java并发编程等. JAVA对象头 由于Java面向对象的思想,在JV ...
- 探究java对象头
探究java对象头 研究java对象头,我这里先截取Hotspot中关于对象头的描述,本文研究基于64-bit HotSpot VM 文件路径 openjdk-jdk8u-jdk8u\hotspot\ ...
- JVM源码分析之Java对象头实现
原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Java对象头实现 HotSpot虚拟机中,对象在内存中的布局分为三 ...
- jvm源码解析java对象头
认真学习过java的同学应该都知道,java对象由三个部分组成:对象头,实例数据,对齐填充,这三大部分扛起了java的大旗对象,实例数据其实就是我们对象中的数据,对齐填充是由于为了规则分配内存空间,j ...
- JAVA对象头
#为了防止自己忘记,先记着,之前我一直以为<深入理解JAVA虚拟机>写错了来着. 一. JAVA对象 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header ...
- Java对象头与锁
对象由多部分构成的,对象头,属性字段.补齐区域等.所谓补齐区域是指如果对象总大小不是4字节的整数倍,会填充上一段内存地址使之成为整数倍. 后面两个很好理解,今天我主要想总结一下对象头: 对象头这部分在 ...
随机推荐
- 20 个免费开源的 CSS3 用户界面工具包
ui.css Metro UI CSS Pure CSS jQuery jKit Solid HTML5/CSS3 UI Kit CSS3 UI Kit Alt CSS3 UI Kit MediaLo ...
- 性别年龄的模块封装类 IDSGenderLeviNamedView
1 IDSGenderLeviNamedView 的实现效果 2 类的封装方法: IDSGenderLeviNamedView.h @interface IDSGenderLeviNa ...
- UItableView UIcollectionView下拉刷新会跳动?看了此篇就能解决这个Bug了
顺序如下: 1.数组添加: for (id model in modellist.list) { IDSCommentWeplayList *commentListModel = [I ...
- python正则表达式模块
正则表达式是对字符串的最简约的规则的表述.python也有专门的正则表达式模块re. 正则表达式函数 释义 re.match() 从头开始匹配,匹配失败返回None,匹配成功可通过group(0)返回 ...
- 【shell学习4》》】系统化整理大纲
之前看的runnoob整理,细节太多也没有系统起来,昨天公交上看了一些视频,略作总结: 标题零:学习基础//创建文件touch testVar.sh //vim编辑内容#!/bin/bashvari= ...
- php5.3之命名空间
在php5.3之后,php像c++那样新 命名空间. 1.在同一个文件中不能实例化同一个名字相同的类和同时包含两个不同目录下的相同文件,中包含相同的函数和常量.为了解决这个问题,因此引入了命名空间. ...
- JS中 【“逻辑运算”,“面试题:作用域问题”,“dom对象”】这些问题的意见见解
1.逻辑运算 || && ! ||:遇到第一个为true的值就中止并返回 &&:遇到第一个为false的值就中止并返回,如果没有false值,就返回最后一个不是fa ...
- Node中的cookie的使用
1.为什么使用cookie? 因为HTTP是无状态协议.简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页面,服务器无法认识到,这是同一个浏览器在访问同一个网站.每一次的访问,都是没有任何关系 ...
- PATB 1019. 数字黑洞 (20)
一个神奇的数字. 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定任一个各位数字不完全相同的4位正整数,如果我 ...
- Python开发【第八篇】: 网络编程
内容概要 楔子 软件开发架构 网络基础 套接字(socket) 粘包 socketserver模块 一. 楔子 现在有两个python文件a.py和b.py,分别运行,这两个程序之间需要传递一个数据, ...