网站建设有什么好的介绍,网站建设如何收费,中铁建设集团有限公司招标平台,wordpress 4.8 中文前言
锁冲突#xff1a;两个线程获取一把锁#xff0c;一个线程阻塞等待#xff0c;一个线程加锁成功。
目录
前言
一、锁策略
#xff08;一#xff09;乐观锁和悲观锁
#xff08;二#xff09;重量级锁和轻量级锁
#xff08;三#xff09;自旋锁和挂起等待…前言
锁冲突两个线程获取一把锁一个线程阻塞等待一个线程加锁成功。
目录
前言
一、锁策略
一乐观锁和悲观锁
二重量级锁和轻量级锁
三自旋锁和挂起等待锁
四读写锁
五公平锁和非公平锁
六可重入锁和不可重入锁
二、原子编程CAS
一实现原子类
二实现自旋锁
三CAS的ABA问题
三、synchronized 优化过程
结语 一、锁策略
一乐观锁和悲观锁
根据加锁之前对锁冲突概率的预测预定工作的多少
乐观锁预测该场景中不太出现锁冲突的情况后续做的工作更少。
悲观锁预测该场景中非常容易出现锁冲突的情况后续做的工作更多。
synchronized初始使用乐观锁策略当发现锁竞争比较频繁时就会自动切换成悲观锁策略。
二重量级锁和轻量级锁
加锁之后考虑实际的锁的开销。
重量级锁加锁的开销越大花的时间越多占用系统资源多。
轻量级锁加锁的开销越小花的时间越少占用系统资源少。
synchronized开始是一个轻量级锁如果锁冲突比较严重就会变成重量级锁。
三自旋锁和挂起等待锁
自旋锁轻量级锁的一种典型实现。在用户态下通过自旋的方式while循环实现类似于加锁的效果消耗一定的CPU资源但可最快速度拿到锁。
挂起等待锁重量级锁的一种典型实现。通过内核态借助系统提供的锁机制当出现锁冲突时会牵扯到内核对于线程的调度使冲突的线程出现挂起阻塞等待消耗的CPU资源少但无法保证第一时间拿到锁。
synchronized中的轻量级锁策略大概是通过自旋锁实现的
synchronized中的重量级锁策略大概是基于系统的互斥锁实现的。
四读写锁
将读操作和写操作分开了。如图 synchronized不是读写锁。
五公平锁和非公平锁
公平锁遵循先来后到的道理。
非公平锁看起来概率相等实际不公平每个线程的阻塞时间不一样。
synchronized是非公平锁。
六可重入锁和不可重入锁
可重入锁如果一个线程争对一把锁连续加锁两次不会出现死锁的情况。
不可重入锁如果一个线程争对一把锁连续加锁两次会出现死锁的情况。
synchronized是可重入锁。
二、原子编程CAS
CAS本质上是一种无锁编程将某个寄存器中的值和内存中的值进行比较如果相等则进行交换。
一实现原子类
可以使用 自增/自减/自增任意值/自减任意值 实现计数、统计这类场景中。
常用的有AtomicInteger、AtomicLong
加锁保证线程安全是通过锁避免出现穿插但是CAS保证线程安全是借助CAS识别当前是否出现穿插的情况如果没有穿插就是安全的穿插了就重新读取内存的最新值再次尝试修改。
二实现自旋锁
获取当前线程的引用判断其是否进行了加锁。加锁了就自旋等待没有加锁就将内置变量owner设为当前尝试加锁的线程。
三CAS的ABA问题
CAS是根据判断内存和寄存器中的值是否相等来进行判断其是否发生改变。但是如果这两者都发生了从A变成B又从B变成了A的情况那我们的CAS就会判断错误从而导致A再次发生变化。
为了解决这类ABA问题就引入了版本号判断版本号是否相等即可。
数据每修改一次版本号就增加一次故此原先的A和后来的A的版本号不同判断结果也就会判断他们不同不会使其发生改变。
三、synchronized 优化过程
synchronized不是一开始就是对我们的代码块处于进行加锁的状态。synchronized的改变是一个自适应的过程 无锁 - 偏向锁 - 轻量级锁 - 重量级锁。
偏向锁不是真的加锁而只是做了一个标记。如果有别的线程来竞争锁了就会真的加锁如果没有其他线程竞争锁就会始终都不会真的加锁。
synchronized还有一些其他的优化操作
锁消除编译器会自动的判断你当前的代码是否有必要加锁。如果你写了锁但实际上没必要加锁就会把锁自动删掉。
锁粗化关于“锁的粒度”。如果加锁操作里包含的实际执行语句多就认为锁的粒度越大。 结语
这篇博客如果对你有帮助给博主一个免费的点赞以示鼓励欢迎各位点赞评论收藏⭐谢谢