线程和锁,锁升级

线程

线程运行的底层原理

程序是什么? 进程是什么? 线程是什么?

  1. 程序: qq.exe Feiqiu.exe 这种静静的躺在硬盘的软件
  2. 进程: 当程序加载到内存进行运行的就是进程资源分配的基本单位
  3. 线程: 是程序执行的基本单位

程序如何运行的? cpu读指令存pc(程序计数器,存储指令地址)里,读数据存Register,计算回写,再下一条指令

线程如何进行调度的? Linux是线程调度器,(os)操作系统

线程切换的概念是什么? Context Switch CPU保存现场执行新线程,恢复现场,继续执行原线程的过程


锁的概念

  1. 当没有抢到锁的时候,会出现忙等待,自旋等待,这种锁叫轻量级锁

  2. 还有就是进入一个等待队列,由操作系统老大来进行调度的,这种锁叫重量级锁

轻量级锁的效率一定比重量级锁的效率高吗?

不是, 原因: 当线程数量太多,而持有锁的线程运行久,其他等待的线程就进行无用的while循环盲目的消耗CPU资源


synchronized关键字

  1. 在jdk1.0和1.2中,直接使用的是重量级锁
  2. 后面升级成了自旋锁

自旋锁CAS

实现方式: 比较并交换

问题: ABA问题?

描述: 就是你拿到的值去比较发现是一样的,但是这个值可能经历了别的线程修改过,又修改回原来的值,所以并不能感觉出来.

解决方法: 加一个版本号,每一次修改都要进行版本号变更

问题: CAS修改值时,的原子性问题?

线程和锁,锁升级

C++代码底层使用了汇编语言 单核下直接使用指令cmpxchg比较并交换,在多核下要使用lock指令,所有的cpu都支持这个指令

lock指令: 锁总线


Synchronized的实现原理

就是Lock指令和comxchg指令,因为它底层使用了轻量级锁,这是一个升级的过程

锁的四种状态

无锁(new出来的时候)–>偏向锁 --> 轻量级锁(CAS) -->重量级锁

偏向锁

没有锁的时候,来一个线程,就贴上一个自己的标签,直接使用,效率的提升就在不用进行判断和竞争

当又来了一个线程或者多个线程,就把标签撕下来,升级成轻量级锁,开始竞争

锁升级

  1. 一个线程偏向锁
  2. 多个线程轻量级锁
  3. 当轻量级锁竞争耗时过长,旋转次数过多,开始进入等待队列,升级成重量级锁

按块读取

程序局部性原理,可以提高效率

充分发挥总线cpu脚针等一次性读取更多数据的能力

缓存行

缓存行越大,局部性空间效率越高,但读取时间慢

缓存行越小,局部性空间效率越低,但读取时间快

取一个折中值,目前多用:64字节

  1. 缓存一致性协议

    cpu为了保持互相缓存行之间的数据的一致性采取的一致性协议, 互相通知和修改值的操作

根据缓存行的特性编程技巧

根据业务将数据进行分离, 让不相关的不要在同一个缓存行,避免了cpu之间的相互达到缓存一致,从而提高了效率