Java 多线程

1. CAS

campare and swap。底层是使用 c++ 实现,其利用汇编的方法 cmpxchg,最终实现是汇编指令

1
2
# 汇编中 lock 指令在执行后面指令是会锁定一个北桥电信号,而不是采用锁总线的方式
lock cmpxchg

2. Java 对象布局

对象布局对象由3部分组成:

  • header:对象头,包含两部分
    • mark word:自身运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,共4字节
    • class pointer:类型指针,即对象指向它的类元数据指针,虚拟机通过它识别其是哪个类的实例,共4字节
  • instance data:实例数据,即实际有效信息,开启压缩时4字节,否则8字节
  • padding:对齐填充,由于 HotSpot 要求对象起始地址必须是 8 的倍数,因此其只是用来在不够时补全

可以使用 JOL(Java Object Layout) 打印出来

1
2
3
4
5
<denpendency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</denpendency>
1
2
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());

3. 锁升级

锁升级过程:对象 -> 偏向锁 -> 轻量级锁(也叫无锁、自旋锁、自适应锁) -> 重量级锁