热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

JDK1.6的锁概念辨析

为什么80%的码农都做不了架构师?偏向锁的目的是消除锁操作中的CAS原语带来的OS开销.CAS原语是由操作系统提供的.CAS在硬件上是由关中断实现的,是非常高级

为什么80%的码农都做不了架构师?>>>   hot3.png

 

偏向锁的目的是消除锁操作中的CAS原语带来的OS开销. CAS原语是由操作系统提供的. CAS在硬件上是由关中断实现的, 是非常高级别的指令, 必须在管态(特权态、核心态)完成. 大部分操作系统都不向用户程序开放RING0. 也就是说, 用户程序是进不了RING0的. 这是操作系统的实现基础 --- > 也可以算作垄断基础的一部分. 

因此CAS的开销其实不小. 它至少需要两个门描述符的切换操作才能完成. 切换本身开销当然不大, 不过修改一下几个CPU内部寄存器的值而已. 大的开销主要在于代码段的切换造成的执行环境变更 --->处理器可能由此抛弃所有的CACHE. 而访问CACHE与访问内存的效率据传相差100倍之多, 所以, 可想而知......

而偏向锁用来消除CAS OS原语的方法其实很简单: 让第一个加锁的线程在锁上留下自己的名字(这个不难做到, 因为很显然一个没有被任何线程获取的锁其线程字段为"空"), 然后每次任何线程尝试加锁时会拿这个名字跟自己的名字比对, 如果一样则不启动任何加锁, 如果不一样则启动加锁.

显然, 只有第一个加锁的线程才能享受到这种福利. 因为任何后来的线程都会在锁上发现"别人"的名字. 说它"偏向", 是相对名字比后的系统行为来说的: 当名字一样时, 它不做任何操作. 这意味着当在比对中发现名字一样时(其实也就是当第一个线程来尝试重复获取锁(在其它锁曾经尝试获取锁以前)时, ), 它不会带给这个线程任何(额外的---因为用户要的是锁, 而不是其它的东西)开销. 在这个意义上, 它"优待"了第一个加锁的线程. 并且显然, 这样的优待也只有第一个加锁的线程才能拥有. 因为所有后续加锁的线程都将因为发现争用而对当前锁启动真正的加锁流程.

也就是说,它的目的是为了消除除第一次CAS操作以外的,不存在争用情况下的后续加锁动作的CAS操作。而 这种优化又显然只有第一次加锁的线程才能得到,这就是Bias的来源: 因为消除CAS操作产生的资源节省,只给第一次加锁的线程。

可以看出,偏向锁的目的是为了在没有竞争的情况下,避免几乎全部的同步开销。其中包括CAS与OS互斥。而其中的CAS,基本上就是轻量级锁的全部开销了:轻量级锁其实是在OS以外VM的同步尝试。

sEr6VcNWQ3MGSJfkYoZB6knsSUGuVEm2zpVYUxJM37QJs8MmlBYJH4A==.jpg

上图所列,其实就是1.6以后的全部的锁。而其它的锁概念如适应性自旋,锁粗化,锁剔除,其实只是行为意义上的锁,并不是真正名词意义上的“锁”。指的其实都是对上图中锁的一些行为优化。

代码可能在下列几种情况下被调用:

1,单线程。无争用(也即无并发);

2,多线程。无争用(也即无并发);

3,多线程。有争用(也即有并发)。

1.6的三个锁层次则分别对应这三种情况:

1,偏向锁(无锁);

2,轻量级锁(VM级);

3,重量级锁(OS级)。

在一个真正的运行时,程序状态必然经历从单线程到多线程无争用到多线程有争用的过程。这正好为锁机制提供了一个逐渐提升锁级别的机会:

1,偏向锁在没有侦测到任何多线程访问的情况下,使系统工作在无锁状态。举个例子,在整个世界只有我一个人居住的情况下,我自然不需要锁。硬要启用这个锁,对我显然将形成一种不必要的负担;

2,轻量级锁在侦测到多线程,也就是说,在整个世界中发现其它人的情况下,我会开始需要一把锁。但是这把锁并不一定要求是互斥的。因为我从来没有发现过其它人在我在家的时候尝试过进入我的房间。在这种从来没有发生过冲突即锁竞争的情况下,互斥是不必要的。但是,锁仍然是必要的。因为它是系统过渡到重量级锁即互斥阶段的必要条件: 系统如何才能知道什么时候应该进入互斥阶段呢? 它必须先知道有一个人占用了锁, 然后才能在第二个人来请求锁的时候才能归纳得到系统当前处于互斥状态的信息。

sTTfLdDTZyHJ6QelroYs4ee17rTplaZNFotdaxHwNxmr4W76SoEGUtg==.jpg

因此可以看出,整个锁系统的逻辑是这样的:

1,如果没有发现多线程的踪迹,那么系统将不会进行任何与锁有关的操作;

2,如果发现了多线程的踪迹,系统将进入轻量级锁阶段。在这个阶段,系统将使用一个替换锁对象mark word的CAS原语来侦测冲突。所以严格上来说,轻量级锁并不是真正的锁,它只是一种用来侦测重量级锁边界条件的操作。所以整个从无锁即偏向锁向重量级锁升级的过程,其实就是系统提供的一种 逐渐进入 真正封锁状态的技术。所有重量级以前的锁,目的并不是为了封锁,因为在它以前并不存在真正的并发操作。所有这些所谓的“锁”,其本质上并不是“锁”。它们所提供的只不过一种使系统“逐渐进入”真正封锁状态的能力。它的哲学是这样的:根据系统的当前状态决定系统的行为(以及由这些系统行为所决定的用户级开销)。系统(或者说程序、临界代码)有三个状态:单线程,多线程,锁竞争。三种锁的提出,分别用来应对这三种状态。而所谓“锁”的逐渐升级过程,只不过是一种状态的逐渐提升过程而已。也就是说,除重量级锁以外所有的其它锁,它们所处理的东西从本质上来说并不是锁或互斥,而是状态侦测。与其命名为轻量级锁与偏向锁,还不如命名为状态侦测锁

因为偏向锁,轻量级锁,,,,这样的词真的很令人费解。

 


转:https://my.oschina.net/digerl/blog/33407



推荐阅读
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 关于CMS收集器的知识介绍和优缺点分析
    本文介绍了CMS收集器的概念、运行过程和优缺点,并解释了垃圾回收器的作用和实践。CMS收集器是一种基于标记-清除算法的垃圾回收器,适用于互联网站和B/S系统等对响应速度和停顿时间有较高要求的应用。同时,还提供了其他垃圾回收器的参考资料。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 统一知识图谱学习和建议:更好地理解用户偏好
    本文介绍了一种将知识图谱纳入推荐系统的方法,以提高推荐的准确性和可解释性。与现有方法不同的是,本方法考虑了知识图谱的不完整性,并在知识图谱中传输关系信息,以更好地理解用户的偏好。通过大量实验,验证了本方法在推荐任务和知识图谱完成任务上的优势。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • SQL Server 内存中OLTP内部机制概述(一)
    内存中OLTP(项目名为“Hekaton”)是一个新的完全集成到SQLServer中的数据库引擎组件。它专为访问内存常驻数据的OLTP工作负荷而进行优化。内存中OLTP有助于OLT ... [详细]
  • 本文介绍了Java虚拟机中的垃圾收集器,包括年轻代收集器Serial收集器、ParNew收集器、Parallel Scavenge收集器,以及老年代收集器Serial Old收集器、Parallel Old收集器和CMS收集器。对每种收集器的算法和特点进行了详细解析,希望对读者有参考价值。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
author-avatar
_我是谁谁谁__950
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有