Java多线程锁机制相关原理实例解析
作者:七月在野,八月在宇 发布时间:2023-05-25 12:33:37
上下文:程序运行需要的环境(外部变量)
上下文切换:将之前的程序需要的外部变量复制保存,然后切换到新的程序运行环境
系统调用:(用户态陷入操作系统,通过操作系统执行内核态指令,执行完回到用户态)用户态——内核态——用户态:两次上下文切换
线程wait()方法:将自身加入等待队列,发生了一次上下文切换
notify()方法:将线程唤醒,也发生了上下文切换
Java线程中的锁:偏向锁、轻量级锁、重量级锁。
注意:偏向锁和轻量级锁都没有发生竞争,重量级锁发生了竞争。
偏向锁:可重入和经常使用某一个线程。
轻量级锁:线程之间的切换,但是未发生竞争(在一个时间段只有一个线程使用)
重量级锁:线程时间的竞争。
临界区:多个线程共享临界区,而且存在对临界区的读写。
无所状态:hashcode 31位年龄age:4位是否是偏向锁:block_lock:一位:0表示不是偏向锁
偏向锁:thread:54位 线程idepoch 2位,作为批量重偏向的记录biased_lock:1 表示为偏向锁
轻量级锁:ptr_to_lock_record:62位表示,锁记录的指针
重量级锁:ptr_to_heavyweight_monitor :62位表示monitor指针
轻量级锁的流程:
锁记录有两个指针:一个指向自身,一个指向lock对象,当lock对象位state位01时,表示位轻量级锁,此时执行轻量级锁的加锁:交换lock record和markword
锁重入:
同样创建一个LockRecord但此时cas失败,因为此时lock对象的markword为当前锁记录的指针,置lockrecord指针为null,表示锁重入,并且添加一个锁重入计数器,记录锁重入的次数
解锁:将LockRecord中的lockrecord(此时是markword)和lock对象(Object)中的markword(lockrecord指针)。如果解锁失败,那么轻量级锁就会膨胀为重量级锁。
重量级锁的加锁、解锁、阻塞、唤醒:只有重量级锁有阻塞
如上图:当发生竞争时,新的线程会将object修改为monitor指针,指向重量级锁的monitor(管程),然后进入等待队列,当当前线程结束同步代码块,就会将owner置为0,此时表示没有线程拥有此锁,然后唤醒其他线程,其他线程就会竞争这个锁。
偏向锁的加锁和解锁:新的线程只需要判断lock对象的markword对象中的线程id是否是自己的id,如果是,那么就直接使用这个锁。不用作cas交换,只有第一次获得此锁时需要用cas交换
调用hashcode可以撤销偏向锁,或者对同一个对象发生锁同步时也会撤销偏向锁
偏向锁重定向:对于一个类的多个实现类锁对象,当超过20次重定向时,后面该锁的实例对象就变成了另外一个线程的偏向锁
当发生40次重定向时,该类的所有lock对象就变成了轻量级锁。
来源:https://www.cnblogs.com/guosai1500581464/p/13413190.html


猜你喜欢
- 代码:public DataTable TXTToDataTable(string fileName, string columnName)
- rpc远程调用可能存在的问题超时的问题。安全的问题。服务与服务之间URL地址管理。在我们的微服务架构通讯,服务之间依赖关系非常大,如果通过传
- 第一种,在配置文件配置在application.xml直接配置,这种方式是全局配置,所有返回给前端对象的属性为null或"&quo
- 一、介绍Mesh类:通过脚本创建或是获取网格的类,网格包含多个顶点和三角形数组。顶点信息包含坐标和所在面的法线。unity中3D的世界的所有
- using System;using System.Collections.Generic;using System.Linq;using
- 通过内部存储方式实现了在两个Activity之间传递Bitmap对象以及其它支持串行化的Java对象,关键点有如下:1. HTT
- 1. 最小生成树连通图中的每一棵生成树 , 都是原图的极大无环子图 , 即: 从中删去任何一条边 , 生成树就不再连通;反之 , 在其中引入
- 本文实例为大家分享了java代码统计小程序,供大家参考,具体内容如下可以测试每周你的工作量package rexExp;import jav
- 记一次 Data Binding 在 library module 中遇到的大坑使用 Data Binding 也有半年多了,从最初的 se
- 本文实例讲述了Android编程之手机壁纸WallPaper设置方法。分享给大家供大家参考,具体如下:/** * Andorid设置手机屏幕
- 一、JAVA简要概述先说一下java之父,詹姆斯·高斯林这是一个爱喝咖啡而又强大的男人。再来看一下JAVA有多火在TIOBE排行榜上JAVA
- 两个简单的例子,代码实现如下:1、随机拆分一个整数public static List<Integer> randomList(
- 本文实例为大家分享了Android九宫格展示的具体代码,供大家参考,具体内容如下(设置的有最少连几个和最大连几个)MainActivityp
- ViewModel的创建方式在我们项目中, 引入了viewModel 做MVI 设计模式的组成部分,它是JetPack 组件库中的重要成员。
- 前言最近在做分块上传的业务,使用到了Redis来维护上传过程中的分块编号。每上传完成一个分块就获取一下文件的分块集合,加入新上传的编号,手动
- 1、SpringMVC中默认集成SpringMVC已经默认集成了JackSon,如下所示: @RequestMapping(&q
- 迪杰斯特拉算法迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算
- 前言对于初学者们来说,刚开始编写Java代码时,会遇到很多困难,下面来说一个比较常见的错误,如下:初学者一般都是从Hello,World开始
- 本文实例讲述了Java开发之spring security实现基于MongoDB的认证功能。分享给大家供大家参考,具体如下:spring s
- 第一步:后端简单建个SpringBoot项目,提供一个 helloWorld接口;版本选用 2.2.6.RELEASEpackage com