多线程学习笔记

synchroized 关键字

java 中的数都是一对象形式进行封装的

在虚拟机中 每个实例化的java对象,具有对应的java对象头

java对象头中含有两部分数据:
1.Mark Word (标记字段)
2.klass Pointer

Mark Word 用来储存对象自身运行时的数据,是实现轻量级锁和偏向锁的重点

klass pointer 意如其名,主要作用的指针,指向该实例对象对应的类元数据。虚拟机主要通过该参数来获取该对象,具体属于哪个类的实例。

Mark Word

包含有:
1.哈希码HashCode
2.GC年龄分带
3.锁状态标志
4.线程持有的锁
5.偏向线程的ID
6.偏向的时间戳等
数据划分如下表所示

25bit 4bit 1bit 2bit
对象的hashcode 对象的年龄分带 是否偏向锁 锁标志位

对象头信息,是对象自定义数据外的,额外用于虚拟机运行的数据存储。 从效率上开率,Mark Word 被设计成一个非固定的数据结构,灵活多年,从而在极小的空间内存存储劲量多的数据。
注意:mark Word会依据对象的状态复用自己的存储空间,会随着程序的运行发生变化

所有的java对象天生自带锁,称之为内部锁或者Monitor锁

Monitor 是县城私有的数据结构,每一个线程都有一个可用的Monitor record列表,同时存在一个全局的可用列表。每一个锁住的对象都会和一个monitor关联(对象头的Mark word 中的LockWord指向Monitor的起始地址),同时Monitor中owner拥有该线程的唯一标识,从而实现了锁和线程的唯一对应关系。

锁的实现理解其来可概括为:

每个线程中存在Monitor 数据结构, 该结构中owner 指向 某一个锁,这个锁定的对象中的mark word中的 LockWord 互相印证,从而获取到锁定的对象。其他对象想要获取对象信息是,判断锁对应的 对象的mark work中的LockWord 是否为null, 为null 时,才会去占有该对象。不为null时,依据不同策略等待被唤起再次尝试获取该对象。

volatile 关键字

volatile 关键字作用范围为某一个对象,再使用过程中可以理解为该多想对所有线程是同时可见的,任意线程对该属性进行修改是,其他线程都能获取到修改后的数据。

实现原理是:

每个线程对应的CPU具有自己的数据缓存区域, 对于被volatile关键字标记的对象,认为该对象在缓存区域的数据无效,强制该线程从公用主存区域取获取该对象。从而实现该过程。

使用volatile 关键姿势,必须保证对该对象的操作是原子性,
所以 还是少用。可用场景为:
1.使用boolean 类型控制循环内的执行,具体

volatile boolean flag = false;
 
while(!flag){
    doSomething();
}
 
public void setFlag() {
    flag = true;
}

你可能感兴趣的:(多线程学习笔记)