并发

缓存行失效的情况

1.如果X存储长度大于一个缓存行,加总线解决

2.cpu并不支持缓存一致性协议

线程分类:用户级线程 ULT,内核级线程 KLT

用户空间划分:用户空间,内核空间

用户和内核直接操作,是通过内核提供的交互接口进行

用户线程通过切换到内核态线程去调度cpu进行线程,只有Ring0级别才能调度cpu,内核态才有Ring0

Tss任务状态断:保存被挂起的线程上下文切换的数据

死锁:两个线程相互持有对方需要的锁对象  jstack 查看死锁

 

JMM的模型:是一种规范  跨平台

线程有工作内存,主内存有共享变量,围绕原子性,可见性,有序性展开

synchronized 关键字 出现线程上下文切换 也会触发去更新主内存的值
线程工作内存的副本,更新完后,会等待一定时间才刷回主内存

查看汇编指令:需要安装对应的插件
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp

内存交互操作的原子比较与交换在底层的支持 cmp-chxg 汇编指令:

read load 成对 store write成对

volatile 保证了 有序性,可见性,但是原子性保证不了,因为for循坏conut值会丢失循坏次数

syn 锁 三个都保证了

有序性:

指令重排的话,前提遵守as-if-serial语义

1.在class字节翻译成机器码的时候,进行指令重排
2.cpu执行汇编指令的时候,也会酌情的进行指令重排

 

synchronized锁升级: 无锁->偏向锁->轻量级锁->重量级锁   (不可逆)

32位mark word :

无锁时:对象的hashcode,对象分代年龄,是否偏向锁,锁标志位

线程进来先判断锁的状态,在mark word修改对应锁的状态,偏向锁是不会自动释放

T2去CAS竞争T1线程的时候,T1还没走完还不释放锁,偏向锁升级为轻量级锁

轻量级锁会复制对象头markword到当前线程栈空间上面,然后对象头markword前29位里面修改成LockRecord对象引用,LockRecord 的owner变量里面是引用指向对象头markword

T1还没走完,T2发起升级重量级锁,JVM会去调线程调度库pthread,从用户态到内核态,这是个比较耗时的操作,把warkword修改成重量级锁的指针,然后调用Pthread_mutex_lock进行线程阻塞挂起,阻塞后会把线程放到waitset等待队列里面去。

T1执行完cas修改warkword发现已经不是指向自己,已经是变成了重量级锁的指针,这时T1会去唤醒阻塞的线程。

AQS:抽象队列同步器 (双向指针的队列)

抽象出等待队列(公平),条件队列(非公平),独占获取,共享获取等待,依赖状态state记录锁的次数(重入,拿一次锁加1,释放时减1)

CLH变种队列(同步队列) 原生CLH队列让线程自旋,而AQS是阻塞

锁类型

是否锁同步资源 :悲观锁和乐观锁

是否阻塞:阻塞  不阻塞(自旋锁,自适应锁)

是否要排队:公平与非公平

一个线程多个线程能不能获取同一把锁:可重入锁与不可重入锁

多个线程能不能共享一把锁:共享锁与排它锁

把两个事情都要干完,两个都是拿得同一个锁,重复的拿到锁

 

你可能感兴趣的:(并发)