多线程进阶

这里涉及的内容是关于实现锁 (不只局限于Java的锁),我们作以了解即可。

1.锁策略

1.悲观锁/乐观锁

悲观锁:发生锁竞争的可能性很大------>逻辑更复杂,就是悲观锁

乐观锁:发生锁竞争的可能性很小------>逻辑更简单,就是乐观锁

2.重量级锁/轻量级锁

重量级锁:加锁这个操作开销大------》重量级锁

轻量级锁:加锁这个开销小------》轻量级锁

"加锁":指的是线程代码执行到synchronized上锁时,尝试占有这把锁的整套执行流程,是cpu执行抢锁的全过程。

重量级锁:涉及用户态核心态切换。线程抢不到锁时,交给OS(Operate System)把线程阻塞挂起,放到等待队列,等锁释放后OS唤醒线程。而在这过程中,涉及用户态切换核心态、线程挂起、线程唤醒,CPU要保存、恢复现场等,开销很大

轻量级锁:只涉及用户态。线程抢不到锁时,不会阻塞线程,而是不断重试尝试抢占锁。轻量级锁的优点是没有线程阻塞唤醒的大开销,但明显的缺点是如果线程一直抢不到锁,CPU一置空转,浪费资源。

悲观锁可能是重量级锁,乐观锁有可能是轻量级锁

3.挂起等待锁/自旋锁

挂起等待锁:线程抢不到锁时,交给OS把线程阻塞,让出CPU,等锁被释放时唤醒线程。涉及操作系统内部线程调度,开销大

自旋锁:遇到锁冲突,不会阻塞线程,而是不断重试尝试抢占锁。

但是,注意!!!

自旋锁与轻量级锁不一样。二者的核心策略一样,但不同的是:

自旋锁:无限空转,一直占有CPU,空耗CPU资源

轻量级锁:JVM轻量级锁的自旋时有限制的自适应自旋。即JVM会自动调整自旋次数,预判很快就能拿到锁------自旋,预判长时间抢不到锁,不会空耗CPU资源,会直接升级为重量级锁,交给OS阻塞休眠。

4.公平锁/不公平锁

公平锁:谁先发起抢锁请求,先进入等待队列,等锁释放后就优先唤醒最早排队的线程

非公平锁:释放锁的瞬间,任何线程都可直接竞争抢锁

synchronized是不公平锁,因为如果是公平锁,锁已被占用,多个线程发起抢锁请求,进入阻塞队列,而阻塞队列的线程要被唤醒,这其中涉及操作系统内部线程调度,开销很大。而如果是公平锁,可减少大量线程唤醒的开销,整体并发吞吐量更高。

5.可重入锁/不可重入锁

可重入锁(递归锁):一把锁可多次加锁

不可重入锁:一把锁不可多次加锁

synchronized是可重入锁

6.读写锁/普通互斥锁

普通互斥锁:普通锁是排他锁。即只要一个线程拿到锁,不管是读还是写,其他线程全都排队阻塞。如果1000个线程全是读操作,那么只能串行排队,并发极低。

读写锁:一个线程拿到锁,其它线程可同时拿到锁。具体情况如下:

线程1读+线程2读------》不会发生锁竞争。效率提高

线程1读+线程2写------》发生锁竞争。读锁在读,写锁必须阻塞等读锁释放后才能拿到写锁;

写锁在修改,其它读锁阻塞,等写锁释放后再拿到读锁。

线程1写+线程2写:------》发生锁竞争。

synchronized是普通互斥锁。

相关推荐
小蒜学长几秒前
基于微信小程序的遇见咖啡店点餐系统设计与实现(代码+数据库+LW)
java·spring boot·后端·微信小程序·咖啡店点餐系统
lisanmengmeng3 分钟前
NRPE 添加命令(三)
java·linux·服务器
IT大白鼠3 分钟前
图数据库系列 · 第 06 篇——避坑汇总:经典生产问题
数据库·nosql·图库数据库
Wang's Blog5 分钟前
Java框架 SpringCloud 快速入门: 网关的 CORS 跨域配置
java·开发语言·spring cloud
驭渊的小故事9 分钟前
NC229023 题解:二分答案求解“最大化最小值“问题
java·算法
江湖有缘10 分钟前
3开源Sqlite数据库管理工具整理合集,可Docker一键部署!
数据库·sqlite·开源
小蒜学长12 分钟前
基于SSM+VUE的电影售票平台的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·ssm框架·电影售票平台
code2cat12 分钟前
【随笔】MCP工具错误怎样分层:先读反馈,再决定下一步
开发语言·后端·ai agent·mcp
朝朝辞暮i22 分钟前
C++ 第 36 课:Action——机械臂/VLA 非常重要
开发语言·c++·算法·ros2
jyOverQ23 分钟前
Redis 持久化怎么做?RDB、AOF 与混合持久化
数据库·redis