线程
线程运行的底层原理
程序是什么? 进程是什么? 线程是什么?
- 程序: qq.exe Feiqiu.exe 这种静静的躺在硬盘的软件
- 进程: 当程序加载到内存进行运行的就是进程资源分配的基本单位
- 线程: 是程序执行的基本单位
程序如何运行的? cpu读指令存pc(程序计数器,存储指令地址)里,读数据存Register,计算回写,再下一条指令
线程如何进行调度的? Linux是线程调度器,(os)操作系统
线程切换的概念是什么? Context Switch CPU保存现场执行新线程,恢复现场,继续执行原线程的过程
锁的概念
-
当没有抢到锁的时候,会出现忙等待,自旋等待,这种锁叫轻量级锁
-
还有就是进入一个等待队列,由操作系统老大来进行调度的,这种锁叫重量级锁
轻量级锁的效率一定比重量级锁的效率高吗?
不是, 原因: 当线程数量太多,而持有锁的线程运行久,其他等待的线程就进行无用的while循环盲目的消耗CPU资源
synchronized关键字
- 在jdk1.0和1.2中,直接使用的是重量级锁
- 后面升级成了自旋锁
自旋锁CAS
实现方式: 比较并交换
问题: ABA问题?
描述: 就是你拿到的值去比较发现是一样的,但是这个值可能经历了别的线程修改过,又修改回原来的值,所以并不能感觉出来.
解决方法: 加一个版本号,每一次修改都要进行版本号变更
问题: CAS修改值时,的原子性问题?
C++代码底层使用了汇编语言 单核下直接使用指令cmpxchg
比较并交换,在多核下要使用lock
指令,所有的cpu都支持这个指令
lock
指令: 锁总线
Synchronized的实现原理
就是Lock
指令和comxchg
指令,因为它底层使用了轻量级锁,这是一个升级的过程
锁的四种状态
无锁(new出来的时候)–>偏向锁 --> 轻量级锁(CAS) -->重量级锁
偏向锁
没有锁的时候,来一个线程,就贴上一个自己的标签,直接使用,
效率的提升就在不用进行判断和竞争
当又来了一个线程或者多个线程,就把标签撕下来,升级成轻量级锁,开始竞争
锁升级
- 一个线程偏向锁
- 多个线程轻量级锁
- 当轻量级锁竞争耗时过长,旋转次数过多,开始进入等待队列,升级成重量级锁
按块读取
程序局部性原理,可以提高效率
充分发挥总线cpu脚针等一次性读取更多数据的能力
缓存行
缓存行越大,局部性空间效率越高,但读取时间慢
缓存行越小,局部性空间效率越低,但读取时间快
取一个折中值,目前多用:64字节
缓存一致性协议
cpu为了保持互相缓存行之间的数据的一致性采取的一致性协议, 互相通知和修改值的操作
根据缓存行的特性编程技巧
根据业务将数据进行分离, 让不相关的不要在同一个缓存行,避免了cpu之间的相互达到缓存一致,从而提高了效率