线程基础知识 03 synchronized锁(对象在内存的布局和加上锁后对象在内存中的变化)
2024-09-08 18:05:13
1 线程不安全演示
public class ThreadAndLockTest1 {
private static int a = 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch la = new CountDownLatch(2);
for (int t = 0;t < 2;t++){
new Thread(()->{
for (int i = 0;i < 100000;i++) {
a++;
}
la.countDown();
}).start();
}
la.await();
System.out.println(a);
}
}
如果线程安全,那么打印结果应该是200000
执行结果,发现不是期望的结果,说明线程不安全
149202
2 锁演示
上面代码加上锁(synchronized)之后
public class ThreadAndLockTest1 {
private static int a = 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch la = new CountDownLatch(2);
for (int t = 0;t < 2;t++){
new Thread(()->{
synchronized (ThreadAndLockTest1.class){
for (int i = 0;i < 100000;i++) {
a++;
}
}
la.countDown();
}).start();
}
la.await();
System.out.println(a);
}
}
执行结果,是期望的结果
200000
3 对象在内存里面的存储布局(Oracle的虚拟机)
什么东西可以作为一把锁?在解释这个问题之前,先了解对象是由什么构成的?
3.1 它主要分为三个部分
对象头:对象头又包括两类:markword,class pointer,
实例数据:instance data,
对齐填充:padding
3.2 markword
它的大小是8字节
1)哈希码、
2)GC年龄分代、
3)锁的信息
锁状态标志
线程持有的锁、
偏向线程id
偏向时间戳
3.3 使用JOL查看对象内存
https://www.cnblogs.com/jthr/p/15980849.html
4 查看上锁对象在内存中布局
上面我们知道了对象的组成和怎么去看对象中的布局,现在我们来看下对象在上锁前、上锁中、上锁后的变化
4.1 示例代码
public class JolTest { static class T{
} public static void main(String[] args) {
T o = new T();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}
4.2 执行结果
发现上锁后对象头中的markword发生的变化,解锁后又恢复了。
上锁实际上是在对象头上做了个标记
001代表无锁
00代表轻量级锁
最新文章
- git命令分类图
- MSSQLServer 纵向表转横向表 横向表转纵向表 行转列 列转行
- Go并发控制之sync.WaitGroup
- Redis在Linux下的安装和启动和配置
- C# 反转字符串
- windows下配置python库
- 2dtoolkit获取sprite像素大小的方法
- UVa 1629 Cake slicing (记忆化搜索)
- VS2015连接Oracle数据库(转)
- css备忘录(关于relative、absolute)
- 阅读INI档 - Delphi一片
- WCF小实例以及三种宿主
- Java 代码性能优化
- 解决NetStream.appendBytes直播爆音的问题解决
- 做一款直播类app
- Git简略教程
- XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)
- MySql 行转列 存储过程实现
- 1920*1080pc端适配
- 使用Java Low Level REST Client操作elasticsearch
热门文章
- 2022春每日一题:Day 37
- 13、设计一个函数process,在你调用他的时候,每次实现不同的功能,输入a,b两个数, 第一次调用时找出a,b中的最大者。 第二次找出最小者,,第三次求两个数的和。
- ssh明文密码小工具:sshpass
- 基于python的数学建模---蒙特卡洛算法
- day27-过滤器Filter02
- day29 jQuery选择器 &; jquery属性操作 &; jquery DOM元素 操作与遍历
- 【每日一题】【栈和队列、双端队列】20. 有效的括号/NC52 有效括号序列-211127/220126
- vue项目中配置scss
- 缓存管理器CacheManager使用
- 记录一次缓存引起的线上BUG