什么是Java自旋锁
目录
- 1.自旋锁
- 2.工作流程
- 3.缺点
- 4.实现原理
- 5.自适应自旋
阻塞或唤醒一个
Java
线程需要操作系统切换CPU
状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。1.自旋锁 在有些场景中,同步资源的锁定时间很短,为了这一小段时间去切换线程,线程挂起和恢复现场的花费可能会让系统得不偿失。
如果机器有多个CPU核心,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃
CPU
的执行时间,看看持有锁的线程是否很快就会释放锁。为了让当前线程“稍等一下”,我们需让当前线程进行自旋,如果在自旋完成后前面锁定同步资源的线程已经释放了锁,那么当前线程就可以不必阻塞而是直接获取同步资源,从而避免切换线程的开销。这就是自旋锁。
2.工作流程
文章图片
3.缺点 自旋锁本身是有缺点的,它不能代替阻塞。自旋等待虽然避免了线程切换的开销,但它要占用处理器时间。
- 如果锁被占用的时间很短,自旋等待的效果就会非常好;
- 如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。
4.实现原理 自旋锁的实现原理同样也是CAS,
AtomicInteger
中调用unsafe
进行自增操作的源码中的do-while
循环就是一个自旋操作,如果修改数值失败则通过循环来执行自旋,直至修改成功。public final int getAndAddInt (Object var1, Long var2, int var4) {int var5; do {var5 = this.getIntVolatile(var1, var2); } while( !this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
5.自适应自旋 自适应意味着自旋的时间(次数)不固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。
- 如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也是很有可能再次成功,进而它将允许自旋等待持续相对更长的时间。
- 如果对于某个锁,自旋很少成功获得过,那在以后尝试获取这个锁时将可能省略掉自旋过程,直接阻塞线程,避免浪费处理器资源。
推荐阅读
- Web 1.0、Web 2.0和Web 3.0有什么区别(有哪些不同?)
- 如何使用SQLMAP测试网站是否存在SQL注入漏洞()
- 投稿|关于当代互联网“七大名著”,这是可以说的吗?
- Android 基础-给有java基础的初学者(四大组件)
- CodeIgniter控制器详解
- 什么是 cURL,它与 API 有什么关系()
- 数据结构|数据结构 - AVL 树
- 本文教你激活windows10
- 本文教你双系统怎样装
- 本文教你win10激活密钥