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代表轻量级锁

  

最新文章

  1. git命令分类图
  2. MSSQLServer 纵向表转横向表 横向表转纵向表 行转列 列转行
  3. Go并发控制之sync.WaitGroup
  4. Redis在Linux下的安装和启动和配置
  5. C# 反转字符串
  6. windows下配置python库
  7. 2dtoolkit获取sprite像素大小的方法
  8. UVa 1629 Cake slicing (记忆化搜索)
  9. VS2015连接Oracle数据库(转)
  10. css备忘录(关于relative、absolute)
  11. 阅读INI档 - Delphi一片
  12. WCF小实例以及三种宿主
  13. Java 代码性能优化
  14. 解决NetStream.appendBytes直播爆音的问题解决
  15. 做一款直播类app
  16. Git简略教程
  17. XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)
  18. MySql 行转列 存储过程实现
  19. 1920*1080pc端适配
  20. 使用Java Low Level REST Client操作elasticsearch

热门文章

  1. 2022春每日一题:Day 37
  2. 13、设计一个函数process,在你调用他的时候,每次实现不同的功能,输入a,b两个数, 第一次调用时找出a,b中的最大者。 第二次找出最小者,,第三次求两个数的和。
  3. ssh明文密码小工具:sshpass
  4. 基于python的数学建模---蒙特卡洛算法
  5. day27-过滤器Filter02
  6. day29 jQuery选择器 &amp; jquery属性操作 &amp; jquery DOM元素 操作与遍历
  7. 【每日一题】【栈和队列、双端队列】20. 有效的括号/NC52 有效括号序列-211127/220126
  8. vue项目中配置scss
  9. 缓存管理器CacheManager使用
  10. 记录一次缓存引起的线上BUG