JUC: 线程锁

news/2025/9/27 12:37:29/文章来源:https://www.cnblogs.com/fei1010/p/19114969

1 面试题复盘

  • 如何理解多线程,如何处理并发,线程池有哪些核心参数?

  • Java加锁有哪几种锁?

  • synchronized原理是什么?为什么可重入?如何获取对象的锁?

  • JVM对原生锁做了哪些优化?

  • 什么是锁清除和锁粗化?

  • 乐观锁是什么?synchronized与乐观锁什么区别?

  • volatile有什么作用?

  • ReentrantLock原理是什么?

  • AQS框架原理介绍一下?

  • 简单说说Lock

  • 是否使用过CountDownLanch? 如何使用?

2 乐观锁与悲观锁

(1)悲观锁

synchronized和Lock都是悲观锁, 同一时间点,有且只有一个线程能够访问对应的资源。 写操作多的场景使用。

(2)乐观锁

认为自己在使用数据时,不会有别的线程修改数据或资源,所以不会添加锁。只是在更新资源的时候,需要去判断当前数据有没有别的线程更新过。判断规则有:

  • 版本号机制version,每一次更新一个版本号。
  • 采用CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。比较并交换

3 锁是什么

(1)锁案例演示 - synchronized的三种应用方式

// 1. 对象锁:对于非静态方法使用synchronized就是加的对象锁,获得的是这个对象(this)作为锁
public synchronized void sentEmail(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("sent email");
}// 2. 类锁:对于静态方法或使用synchronized就是加的类锁,获得的是这个类对象(.class)作为锁
public static synchronized void sentSMS(){System.out.println("sent SMS");
}// 3. 代码块,使用的是synchronized括号内的对象
public void testSynchronized(){synchronized (this){System.out.println("testSynchronized");}
}

(2)从字节码角度分析synchronized实现

  • javap -c ***.class文件反编译
javap -c a.class # 	​​反汇编代码​​,输出每个方法的 Java 字节码指令(指令集)
-v或 -verbose # 输出​​最详细的附加信息​​,包括版本号、常量池、方法描述符(签名)、栈大小等
  • synchronized同步代码块
public void testSynchronized(){synchronized (this){System.out.println("testSynchronized");}
}
public void testSynchronized();Code:0: aload_01: dup2: astore_13: monitorenter # 获取锁4: getstatic     #26                 // Field java/lang/System.out:Ljava/io/PrintStream;7: ldc           #44                 // String testSynchronized9: invokevirtual #34                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V12: aload_113: monitorexit # 释放锁14: goto          2217: astore_218: aload_119: monitorexit # 异常情况也可以释放锁20: aload_221: athrow22: returnException table:from    to  target type4    14    17   any17    20    17   any
}
  • synchronized对象锁

-v

public synchronized void sentEmail(){System.out.println("sent email");
}
  public synchronized void sentEmail();descriptor: ()Vflags: (0x0021) ACC_PUBLIC, ACC_SYNCHRONIZED # 会检查对象的ACC_SYNCHRONIZED是否被设置,如果设置了,则会持有monitor直到方法完成释放Code:stack=2, locals=1, args_size=10: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #13                 // String sent email5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 31: 0line 32: 8LocalVariableTable:Start  Length  Slot  Name   Signature0       9     0  this   Lcom/thread/sgg/juc/Phone;
  • synchronized类锁
public static synchronized void sentSMS(){System.out.println("sent SMS");
}
  public static synchronized void sentSMS();descriptor: ()Vflags: (0x0029) ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED # 根据是否有ACC_STATIC是否存在判断应该是类锁还是对象锁Code:stack=2, locals=0, args_size=00: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #21                 // String sent SMS5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 34: 0line 35: 8

(3)反编译synchronized锁的是什么

为什么任何一个对象都可以成为一个锁?

Object是任何类的父类

什么是管程monitor?

monitor是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。

这些共享资源一般是硬件设备或一群变量。对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对象内部)管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。管程提供了一种机制,管程可以看做一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。

//结构体如下
ObjectMonitor::ObjectMonitor() {  _header       = NULL;  _count       = 0;   // 该线程获取锁的次数_waiters      = 0,  _recursions   = 0;       //线程的重入次数_object       = NULL;  _owner        = NULL;    //标识拥有该monitor的线程_WaitSet      = NULL;    //等待线程组成的双向循环链表,_WaitSet是第一个节点_WaitSetLock  = 0 ;  _Responsible  = NULL ;  _succ         = NULL ;  _cxq          = NULL ;    //多线程竞争锁进入时的单向链表FreeNext      = NULL ;  _EntryList    = NULL ;    //_owner从该双向循环链表中唤醒线程结点,_EntryList是第一个节点_SpinFreq     = 0 ;  _SpinClock    = 0 ;  OwnerIsThread = 0 ;  
}  

4 公平锁与非公平锁

公平锁:多个线程按照申请锁的顺序获取锁

非公平锁:不按照顺序获取锁,可能导致某些线程处于饥饿状态

为什么有公平和非公平锁的设计?为什么默认非公平锁?

非公平锁能减少线程切换,减少CPU空闲状态的时间,效率较高。

public class ReentrantLock implements Lock, java.io.Serializable {abstract static class Sync extends AbstractQueuedSynchronizer {...}/*** Sync object for non-fair locks*/static final class NonfairSync extends Sync {...}/*** Sync object for fair locks*/static final class FairSync extends Sync {...}public ReentrantLock() {sync = new NonfairSync();}public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}

5 可重入锁(递归锁)

是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提,锁对象得是同一个对象),不会因为之前已经获取过还没释放而阻塞。

  • 可重入锁的种类
    • 隐式:synchronized(自动多次释放)
    • 显示:ReentrantLock(手动多次释放)

6 死锁及排查

死锁是指两个或两个以上的线程在执行过程中,因争夺双方持有的资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足!死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。

jps  # 查看Java进程编号
jstack 进程编号 # 查看死锁情况

7 写锁(独占)与读锁(共享)

8 自旋锁SpinLock

9 无锁-独占锁-读写锁-邮戳锁

10 无锁-偏向锁-轻量锁-重量锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/919463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机网站是怎么制作的wordpress好玩插件

1.新建Android应用,确定应用包名 2.注册高德开放平台,打开控制台页面,应用管理,我的应用,创建新应用 3.添加Key 4.获取SHA1码 找到Android Studio自带的keytool 将其拖到cmd中,输入命令 -v -list -keystor…

网站在线咨询模块东营市招投标信息网

🎉博主首页: 有趣的中国人 🎉专栏首页: Linux 🎉其它专栏: C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好,本片文章将会讲解Linux中项目自动化构建工具make/makefile的相关内容。 如果看到最后…

dede网站地图怎么做lamp网站开发 pdf

为什么80%的码农都做不了架构师?>>> 介绍 在本系列的第一篇文章中,安装了Node.js、Ignite的Node.js瘦客户端包,并且测试了一个示例应用。在本文中,可以看一下Ignite在处理其它数据源(比如关系数据库&#…

InteractiveCommunication Problems

/偏向于前者。CSP 初赛塞了两个交互,有点慌。

JSON 框架混用避坑指南:FastJSON vs Jackson

`com.alibaba.fastjson.JSON.parseObject()` 方法无法识别 Jackson 的 `@JsonProperty` 注解,导致字段映射失败。 核心矛盾:FastJSON 无法识别 Jackson 的 @JsonProperty 注解目录一、问题定位二、框架对比表三、典…

实用指南:网络通信协议全解析:HTTP/UDP/TCP核心要点

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

企业级大数据技术栈:基于Hadoop+Spark的全球经济指标分析与可视化环境实践

企业级大数据技术栈:基于Hadoop+Spark的全球经济指标分析与可视化环境实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-famil…

网站制作的相关术语西安专业做网站建

连接MySQL数据库时常见故障问题的分析与解决 初学的mysql网友好象经常会碰到mysql无法连接的错误。特开贴收集这样问题的现象和原因。 先自己扔块砖头出来。 归纳如下: 故障现象 : 无法连接 mysql 错误信息1 :ERROR 1045 (28000): Access deni…

若邻接矩阵是三角矩阵,则存在拓扑序列;反之则不一定成立

目录1. 命题回顾2. 前半句:邻接矩阵是三角矩阵 ⇒ 存在拓扑序列2.1 邻接矩阵是上三角矩阵的情况2.2 邻接矩阵是下三角矩阵的情况3. 后半句:反之则不一定成立4. 最终判断1. 命题回顾若邻接矩阵是三角矩阵,则存在拓扑…

Gateway-断言 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

macOS 多 Java 版本管理(jenv 方案)

目录一、目标二、查看已安装的 JDK三、使用 jenv 管理 Java 版本1. 安装 jenv2. 配置 Shell 环境3. 添加已安装的 JDK4. 查看可用版本5. 切换 Java 版本6. 验证版本四、常见问题1. 权限问题2. Shell 配置文件选择错误五…

龙口网站制作价格衡阳网站建设技术外包

操作: 是时机函数,在页面加载前,可以在这两个函数里面做一些事情, 比如发送异步请求。 类似过滤器,或者拦截器。1. axios安装 安装报错,多装几遍,或者用cnpm安装 npm install axios -s npm in…

怎么提高网站关键字排名网站怎么做360免费优化

在数字化浪潮席卷全球的今天,跨境电商业务蓬勃发展,成为推动国际贸易增长的重要引擎。亚马逊,作为全球最大的电商平台之一,以其独特的平台特点和全球化布局,为卖家和买家提供了便捷、高效的交易环境,成为众…

广州搜索seo网站优化建设银行网站字体

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

AI 落地教育智慧招生:从 “热线占线” 到 “724 小时精准应答” 的实践分享

AI 落地教育智慧招生:从 “热线占线” 到 “724 小时精准应答” 的实践分享在教育招生季,家长对 “报名时间”“学区范围”“学校特色” 的咨询需求集中爆发,而传统招生咨询模式往往陷入 “家长急、老师累、效率低”…

软件技术基础第一次课程

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/25rjjc 这个作业的目标 初步学习博客的发文方法,进行自我评估,有初步的认知 姓名-学号 林靖迪- 2023329301118自我介绍与自我评估自我介绍 我叫林靖迪,是…

服装网站策划设计重庆手机网站制作价格

过几天就要回家了,剩下的工作还有一点没有完成.不过已经是无关大碍了.突然有种很烦的感觉.想想这个暑假的时间里面自己也算是经历不少了,可是回忆一下自己到底收获了什么,脑子里面却是一片空白,什么都想不到.本来是要动笔写篇"我的深圳之行"之类的东西的,可是却没有一…

做网站推广怎么找客户临安区做网站的公司

实现一个标准型计算器及其各项功能的实现 效果图欣赏 是不是看起来很漂亮的呢??? 功能详解: 屏幕显示输入的数字和符号实现加减乘除运算回退和清零功能小数的运算结果的输出 相信小伙伴们都已经迫不及待的想要知道源码了。 代…