当前位置: 首页 > news >正文

[JAVAEE] 面试题(一) - 锁策略, synchronized的详细介绍

目录

一. 锁策略

1.1 什么是锁策略

1.2 悲观锁 vs 乐观锁 (加锁时遇到的场景)

1.3 重量级锁 vs 轻量级锁 (遇到某一种场景后的解决方案)

1.4 挂起等待锁 vs 自旋锁 (解决方案的典型实现)

1.5 普通互斥锁 vs 读写锁

1.6 可重入锁 vs 不可重入锁

1.7 公平锁 vs 非公平锁

二. synchronized的详细介绍

2.1 锁升级

2.2 锁消除

2.3 锁粗化

三. 总结


一. 锁策略

1.1 什么是锁策略

锁在加锁的时候, 会有哪些特征和行为.

1.2 悲观锁 vs 乐观锁 (加锁时遇到的场景)

悲观锁: 加锁的时候, 预测接下来的锁竞争会非常激烈, 就需要针对这种情况做一些额外的工作.

乐观锁: 加锁的时候, 预测接下来的锁竞争不激烈, 就不需要做额外的工作.

注: 悲观和乐观不是特指某一种锁, 而是指锁具有这样的特性.

1.3 重量级锁 vs 轻量级锁 (遇到某一种场景后的解决方案)

重量级锁: 在悲观的场景下, 需要付出更多的代价. => 更低效

轻量级锁: 在乐观的场景下, 付出更少的代价. => 更高效

1.4 挂起等待锁 vs 自旋锁 (解决方案的典型实现)

挂起等待锁: 操作系统内核级别的, 当前线程遇到锁竞争之后阻塞(不消耗cpu资源), 等待操作系统内核来唤醒. (锁竞争激烈, 一个线程阻塞后不知道什么时候能获取锁, 就挂起等待, 此时, 不消耗资源)

自旋锁: 应用程序级别的, 当前线程遇到锁竞争之后忙等(while...)(疯狂消耗cpu资源), 等待竞争结束.

(锁竞争不激烈, 一个线程阻塞后(没有真的阻塞, 而是忙等), 很快就可以获取锁, 就忙等)

悲观锁 => 重量级锁 => 挂起等待锁

乐观锁 => 轻量级锁 => 自旋锁

1.5 普通互斥锁 vs 读写锁

synchronized是普通互斥锁: 加锁 解锁

读写锁: 读与读不互斥, 读与写互斥, 写与写互斥 因为读是线程安全的, 写是线程不安全的.(读多写少的场景)

1.6 可重入锁 vs 不可重入锁

synchronized是可重入锁.

ReentrantLock默认状态下是不可重入锁, 可以设置为可重入锁.

面试题: 如何实现一个可重入锁? (重要)

加锁时: 第一次加锁时, 记录当前是哪个线程进行加锁. 之后每次进行加锁时, 判断是否是第一次记录时的线程加锁.并且原子类count进行自增+1操作.

解锁时: 原子类count进行自减-1操作, 减到0时, 第一次记录的线程释放锁.

1.7 公平锁 vs 非公平锁

公平锁: 线程获取锁讲究先来后到.

非公平锁: 线程获取锁不要求先来后到.

synchronized是非公平锁.

ReentrantLock 默认是非公平锁, 可以设置为公平锁.


二. synchronized的详细介绍

2.1 锁升级

无锁 => 偏向锁 => 轻量级自旋锁 => 重量级挂起等待锁

偏向锁: 不是真的锁, 而是标记.

拿到偏向锁(没有真的加锁, 只是标记)的线程在运行的过程中, 遇到了其他的线程竞争这个锁, 拿到偏向锁的线程就会抢先一步真加锁.

2.2 锁消除

jvm判断当前代码逻辑是否需要加锁, 若不需要, jvm就会优化代码(锁消除). 

2.3 锁粗化

把一些连续的.细粒度的加锁优化成一次粗粒度的加锁.


三. 总结

1. 悲观锁, 乐观锁(不是某一种具体的锁, 而是锁具有这样的特性) (加锁时遇到的场景) 

2. 重量级锁, 轻量级锁(遇到某一种场景时的解决方案)

3. 挂起等待锁(阻塞), 自旋锁(忙等)(解决方案的典型实现)

4. 悲观锁 => 重量级锁 => 挂起等待锁

    乐观锁 => 轻量级锁 => 自旋锁

5. 普通互斥锁, 读写锁

6. 可重入锁, 不可重入锁 (可重入锁的实现)

7, 公平锁, 非公平锁

8, synchronized是自适应的, 普通互斥锁, 可重入锁, 非公平锁

9, 锁升级(无锁 -> 偏向锁 -> 轻量级自旋锁 -> 重量级挂起等待锁)

10, 锁优化

11, 锁粗化(将连续的, 细粒度的加锁优化成为一次粗粒度加锁)


http://www.mrgr.cn/news/60662.html

相关文章:

  • 51c嵌入式~IO合集1
  • 负载均衡详解:背景、实现技术、作用范围与常用算法
  • C语言二刷指针篇
  • 图像处理 -- 白平衡处理简介
  • 基于PHP的http字段查询与注册(V1)(持续迭代)
  • 华为OD机试 - 信息搜索(Python/JS/C/C++ 2024 D卷 100分)
  • 【HTML】之基本标签的使用详解
  • GitHub每日最火火火项目(10.28)
  • Linux内核-sys虚拟文件系统
  • TypeScript -枚举知识点详解
  • labelimg使用教程
  • Springboot整合spring-boot-starter-data-elasticsearch
  • C++入门基础知识129—【关于C 库函数 - time()】
  • 论可以对抗ai编程的软件开发平台(直接把软件需求描述变成软件的抗ai开发平台)的设计
  • Java:String类(超详解!)
  • Vue3与pywebview前后端初步通信
  • java保留两位小数
  • 10月28日,每日信息差
  • Python xlrd库介绍
  • stm32入门教程--DMA
  • Python:现代编程的必备技能
  • 程序设计挑战赛A卷
  • CXL与近内存计算结合,会发生什么?--part2
  • 流量特征分析-常见攻击事件 tomcat
  • python3的基本数据类型:List(列表)创建与索引
  • 存储引用服务(OSS)Minio 环境搭建