Java多线程锁机制相关原理实例解析

作者:七月在野,八月在宇 时间:2023-05-25 12:33:37 

上下文:程序运行需要的环境(外部变量)

上下文切换:将之前的程序需要的外部变量复制保存,然后切换到新的程序运行环境

系统调用:(用户态陷入操作系统,通过操作系统执行内核态指令,执行完回到用户态)用户态——内核态——用户态:两次上下文切换

线程wait()方法:将自身加入等待队列,发生了一次上下文切换

notify()方法:将线程唤醒,也发生了上下文切换

Java线程中的锁:偏向锁、轻量级锁、重量级锁。

注意:偏向锁和轻量级锁都没有发生竞争,重量级锁发生了竞争。

偏向锁:可重入和经常使用某一个线程。

轻量级锁:线程之间的切换,但是未发生竞争(在一个时间段只有一个线程使用)

重量级锁:线程时间的竞争。

临界区:多个线程共享临界区,而且存在对临界区的读写。

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指针

轻量级锁的流程:

Java多线程锁机制相关原理实例解析

锁记录有两个指针:一个指向自身,一个指向lock对象,当lock对象位state位01时,表示位轻量级锁,此时执行轻量级锁的加锁:交换lock record和markword

锁重入:

Java多线程锁机制相关原理实例解析

同样创建一个LockRecord但此时cas失败,因为此时lock对象的markword为当前锁记录的指针,置lockrecord指针为null,表示锁重入,并且添加一个锁重入计数器,记录锁重入的次数

解锁:将LockRecord中的lockrecord(此时是markword)和lock对象(Object)中的markword(lockrecord指针)。如果解锁失败,那么轻量级锁就会膨胀为重量级锁。

重量级锁的加锁、解锁、阻塞、唤醒:只有重量级锁有阻塞

Java多线程锁机制相关原理实例解析

如上图:当发生竞争时,新的线程会将object修改为monitor指针,指向重量级锁的monitor(管程),然后进入等待队列,当当前线程结束同步代码块,就会将owner置为0,此时表示没有线程拥有此锁,然后唤醒其他线程,其他线程就会竞争这个锁。

偏向锁的加锁和解锁:新的线程只需要判断lock对象的markword对象中的线程id是否是自己的id,如果是,那么就直接使用这个锁。不用作cas交换,只有第一次获得此锁时需要用cas交换

调用hashcode可以撤销偏向锁,或者对同一个对象发生锁同步时也会撤销偏向锁

偏向锁重定向:对于一个类的多个实现类锁对象,当超过20次重定向时,后面该锁的实例对象就变成了另外一个线程的偏向锁

当发生40次重定向时,该类的所有lock对象就变成了轻量级锁。


来源:https://www.cnblogs.com/guosai1500581464/p/13413190.html

标签:Java,多,线程,锁
0
投稿

猜你喜欢

  • 如何让Spring Rest 接口中路径参数可选

    2022-02-17 19:29:14
  • Android 判断某个Activity 是否在前台运行的实例

    2023-07-24 19:29:21
  • Android仿新浪微博发送菜单界面的实现

    2022-12-13 10:54:03
  • Spring Boot 2结合Spring security + JWT实现微信小程序登录

    2022-07-14 08:25:54
  • Java服务假死之生产事故的排查与优化问题

    2022-01-12 04:03:37
  • c# WPF中的TreeView使用详解

    2021-05-24 15:17:58
  • C++ 实现球迷 今日头条面试题

    2022-07-08 11:03:24
  • Android Studio导入jar包过程详解

    2023-01-02 08:04:51
  • Java实现小型图书馆管理系统

    2021-06-14 04:27:35
  • android RecyclerView实现条目Item拖拽排序与滑动删除

    2023-03-20 20:50:36
  • Android 中TextView中跑马灯效果的实现方法

    2023-08-07 01:39:46
  • Android AIDL和远程Service调用示例代码

    2022-07-14 03:06:15
  • java实现Dijkstra最短路径算法

    2022-11-30 21:02:15
  • spring系列笔记之常用注解

    2022-02-21 16:15:04
  • Struts2下拉框实例解析

    2021-09-16 16:29:59
  • Android获取apk签名指纹的md5值(防止重新被打包)的实现方法

    2023-06-23 04:26:12
  • C#字符串和Acsii码相互转换

    2022-09-24 00:12:07
  • springBoot @Scheduled实现多个任务同时开始执行

    2023-06-19 23:16:41
  • C#中foreach语句使用break暂停遍历的方法

    2022-10-12 20:14:11
  • 鸿蒙开源第三方组件之连续滚动图像组件功能

    2023-02-21 06:34:44
  • asp之家 软件编程 m.aspxhome.com