Java锁的升级策略是什么

技术Java锁的升级策略是什么本篇内容主要讲解“Java锁的升级策略是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java锁的升级策略是什么”吧!这三种锁是指锁的状态,

本文主要讲解“Java锁的升级策略是什么”。感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖学习“Java锁的升级策略是什么”!

这三种锁指的是锁的状态,它们特定于Synchronized关键字。JDK 1.6为了降低“重量级锁”的性能消耗,引入了“偏向锁”和“轻量锁”。锁有四种状态:解锁状态、偏置锁、轻量锁和重量锁。锁定状态由对象标题中的标记字标记:

锁可以升级但不能降级,这意味着偏置锁升级为轻量锁后不能降级为偏置锁。这种升级锁但不能降级的策略是为了提高获取和释放锁的效率。

重量级锁:根据底层操作系统的互斥锁,线程会被阻塞。

缺点:锁定和解锁需要从用户模式切换到内核模式,消耗大量性能。

轻量级锁:基于重量级锁进行优化(避免上下文切换,提高性能)。它假设多线程竞争是交错的,不会发生线程阻塞,因此上下文切换是多余的。

第一个特点:采用CAS操作进行锁定和解锁,由于轻量级锁的Lock Record存储在对象头和线程空间,锁定和解锁不需要上下文切换,性能消耗小。

第二个特点:一旦发生多线程竞争,首先基于“自旋锁”的思想,自旋CPU会等待一段时间而不进行上下文切换,如果仍然无法获得锁,那么锁将升级为重量级锁。

偏锁:基于轻量锁进行优化(减少多次加锁和解锁,提升性能)。它假设在整个过程中只有一个线程获得锁,因此多次锁定和解锁是多余的。

特点:第一次获取锁后不会释放锁,会一直持有锁,以后进入锁时只需要检查锁状态和偏置的线程ID是否是自己的,省去了多次加锁和解锁。

1.偏向锁

获取锁定:

检查对象头的Mark Word是否可偏转(即是否偏向锁1,锁标志位是否为01),如果不是,尝试争锁:尝试CAS操作,将Mark Word的线程ID设置为当前线程ID,表示线程已经获得锁,如果失败,则说明锁已经被占用。

如果是可偏转的,检查线程标识是否是当前线程标识。如果是,说明当前线程已经持有锁(锁可以重新进入),否则说明锁已经被占用。

如果锁已被占用,您只能将偏置锁撤销为无锁或轻量锁。

释放锁:(bias锁采用等待竞争释放锁的机制,线程不会主动释放bias锁,只有当其他线程竞争bias锁时,持有Bias锁的线程才会释放锁)

有偏锁的撤销需要等待全局安全点(此时没有正在执行的字节码),停止持有有偏锁的线程,检查持有有偏锁的线程是否还活着。

如果线程挂起,将对象头设置为解锁状态;如果线程还活着,将对象头设置为轻量级锁(锁升级),轻量级锁最终会被释放。

2.轻量级锁

获取锁定:

检查对象头的Mark Word是否是轻量级锁(锁标志位为00),如果不是,尝试竞争锁:JVM首先在当前线程的栈帧中建立一个Lock Record,用于备份存储对象头的Mark Word(这个副本的官方前缀被一个Displaced mark word替换)。然后JVM尝试CAS操作,将标记字更新为指向锁记录的指针,以指示线程已经获得锁。如果失败,说明锁已经被占用了。

如果是轻量级锁,则判断对象头的Mark Word是否指向当前线程栈帧的Lock Record。如果是,则表示当前线程已经持有锁(锁可以重新进入),否则表示锁已经被占用。

如果锁已被占用,当前线程将尝试旋转CPU以获取锁。旋转一定次数后,轻量级锁将扩展为重量级锁(锁标志位变为10),线程将进入块。

释放锁定:

尝试CAS操作,将移位的标记字替换回目标

如果CAS操作失败,意味着有锁竞争,锁已经膨胀成了重量级的锁。有必要在释放锁的同时唤醒挂起的线程。

3.重量级锁

重量级锁依赖于底层操作系统的Mutex Lock,所有线程都会被阻塞,线程之间的切换需要从用户状态切换到内核状态,成本非常高。

总结:锁的优缺点比较

有偏锁锁定和解锁不需要额外的消耗,与异步方法相比只有纳秒的差距。如果线程之间存在锁竞争,就会带来额外的锁取消。适用于只有一个线程访问轻量级Lock竞争的线程,不会阻塞,提高了程序的响应速度。对于得不到锁的线程,spin会消耗CPU追求的响应时间,或者要求临界区短,Spin不会占用CPU太长时间。重量级Lock线程竞争不会使用spin,不会消耗CPU资源,线程阻塞,且响应时间慢会追求吞吐量。

至此,相信大家对“Java锁的升级策略是什么”有了更深的理解,让我们在实践中去做吧!这是网站。更多相关内容,可以去相关渠道查询,关注我们,继续学习!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/105120.html

(0)

相关推荐

  • c语言如何查询结构体中的数据(数据结构的链表怎么连接c语言)

    技术如何进行数据结构C语言链表的实现这篇文章将为大家详细讲解有关如何进行数据结构C语言链表的实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前言需要用到的函数库#inc

    攻略 2021年12月18日
  • 前端代码注释规范

    技术前端代码注释规范 前端代码注释规范前端代码注释规范
    目的和原则
    提高可读性和可维护性
    如无必要,勿增注释;如有必要,尽量详尽
    语法和快捷键
    单行注释:// 快捷键: ctrl+/
    多行注释:/**/

    礼包 2021年11月25日
  • AcWing 91 最短Hamilton路径

    技术AcWing 91 最短Hamilton路径 AcWing 91 最短Hamilton路径AcWing 91 最短Hamilton路径
    题目描述
    给定一张 n个点的带权无向图,
    点从 0~n?1 标

    礼包 2021年11月19日
  • C#如何实现Winform自动升级程序

    技术C#如何实现Winform自动升级程序这篇文章给大家分享的是有关C#如何实现Winform自动升级程序的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。开发第三方工具包新建一个WinForm项

    攻略 2021年12月1日
  • ThinkPHP3.2如何实现中英文切换

    技术ThinkPHP3.2如何实现中英文切换这篇文章主要介绍了ThinkPHP3.2如何实现中英文切换,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.

    攻略 2021年11月19日
  • MongoDB可视化工具的使用方法

    技术MongoDB可视化工具的使用方法今天就跟大家聊聊有关MongoDB可视化工具的使用方法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 MongoDB 是一种

    攻略 2021年11月3日