java8锁
文章目录
锁同步资源,线程状态
多线程竞争同步资源的流行细节
一个线程中有多个流程能不能获取同一把锁?
多线程能不能共享同一把锁
java关键字 synchronized 和 对象 Lock 都是悲观锁
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoTGfhAF-1650169417865)(java8锁.assets/image-20220416131834417.png)]
CAS算法 Compare And Swap 比较与交换
private ReetrantLock lock = new ReentrantLock();
void myLokc(){
lock.lok();
//同步操作
lock.unlock();
}
自旋锁 VS 适应性自旋锁
自旋锁
unsafe
操作内容 | 说明 |
---|---|
内存 | 分配、拷贝、扩充、释放堆外内存 设置、获取给定地址中的值 |
CAS | |
Class | 动态创建类(普通类&匿名类) 获取field的内存地址偏移量 检查、确保类初始化 |
对象操作 | 获取对象成员属性在内存偏移量 非常规对象实例化 储存、获取指定偏移地址变量值(包含延迟生效、volatile语意义) |
数组相关 | 返回数组元素内存大小 返回数组首元素偏移地址 |
内存屏障 | 禁止load、store重排序 |
系统相关 | 返回内存页大小 返回系统指针大小 |
线程调度 | 线程挂起、恢复 获取、释放锁 |
自适应自旋锁
无锁->偏向锁->轻量锁->重量锁
无锁
无锁没有对资源进行锁定、所有线程都能访问同一个资源,但同时只有一个线程能修改成功。
无锁的特点就是修改操作在循环内,线程会不断的尝试修改共享资源。如果没有冲突就修改成功并退出,否则会继续循环尝试。如果有多个线程修改同一个值,必定会有一个线程能修改成功,而其他修改失败的线程会不断重试直到修改成功。CAS原理及应用即是无锁实现的。无锁无法全面代替有锁。无锁在某些场景下性能非常高。
偏向锁
偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。
在大多数情况下,锁总是由同一线程多次获得,不存在多线程竞争,所有出现了偏向锁。其目的就是在只有一个线程执行同步代码块时能够提高性能。
当一个线程访问同步代码块并获取锁时,会在mark word里存储偏向线程id。在线程进入和退出同步块时不在通过CAS操作来加锁和解锁。偏向锁时为里在无锁线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量锁获取及释放锁依赖CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令即可。
偏向锁只有遇到其他线程竞争偏向锁时,持有偏向锁的线程才会释放锁,线程不会主动释放偏向锁。偏向锁的撤销,需要等待全局安全点(这个时间点上没有字节码正在执行)先暂停拥有偏向锁的线程,判断对象是否处于锁定状态。撤销偏向锁后恢复到无锁(标志01)或轻量级锁(00)状态
轻量级锁
当锁时偏向送锁的时候,被另外的线程锁访问,偏向锁会升级为轻量锁,其他线程会通过自旋的形式获取锁,不会阻塞,从而提高性能。
在代码进入同步代码块的时候,如果同步对象锁的状态为无锁状态(锁标志位 01 ,是否为偏向锁 0) ,虚拟机首先将当前线程的展帧中建立一个名为锁记录(lock Record)空间,用于存储锁的对象目前的Mark Word的拷贝,然后拷贝对象头中Mark Word复制到锁记录中。
拷贝成功后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针。
如果这个操作成功,那么这个线程就用于两该对象的锁,并且对象Mark Word的锁标志位设置为“00”,表示对象处于轻量级锁状态。
若当前只有一个等待线程,则该线程痛殴自旋进行等待。但时当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访问,轻量锁升级为重量锁。
重量级锁
锁的标志位改为 01 线程进入阻塞状态。
公平锁、非公平锁
公平锁
可重入锁、非可重入锁
可重入锁
可重入锁又名递归锁,是同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁得是同一个对象或class),不会应为之前已经获取过还没释放而阻塞。java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可以一定程度避免死锁
class test{
synchronized void mothed1(){ mothde2();}
synchronized void mothed2(){}
}
非可重入锁
共享锁、独享锁
独享锁:排他锁,线程对共享数据添加了排他锁后,其他线程不能在对数据有任何类型加锁。
共享锁:资源被线程上了共享锁后,其他线程只能读取资源,不能操作。