LockSupport常用方法源码分析
前言:本文将介绍LockSupport类中的方法和部分源码,以及面试常问到的一个小问题,感兴趣的大佬可以指点下。
希望能够加深自己的印象以及帮助到其他的小伙伴儿们😉😉。
如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。
小威在此先感谢各位大佬啦~~🤞🤞

🏠个人主页:小威要向诸佬学习呀
🧑个人简介:大家好,我是小威,一个想要与大家共同进步的男人😉😉
目前状况🎉:24届毕业生,曾经在某央企公司实习,目前在某税务公司实习👏👏💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬😘
以下正文开始

LockSupport类常用方法源码
LockSupport只是一个简单的基础类,位于java.util.concurrent.locks包下,多用于线程的阻塞和唤醒,因此LockSupport也被称为其他线程的工具类。
LockSupport类的源码有标注,LockSupport类无法实例化。LockSupport类的底层是有Unsafe类实现的,LockSupport加载时的初始化也用到了Unsafe获取成员的偏移量,其源码如下:
// Hotspot implementation via intrinsics APIprivate static final sun.misc.Unsafe UNSAFE;private static final long parkBlockerOffset;private static final long SEED;private static final long PROBE;private static final long SECONDARY;static {try {UNSAFE = sun.misc.Unsafe.getUnsafe();Class<?> tk = Thread.class;parkBlockerOffset = UNSAFE.objectFieldOffset(tk.getDeclaredField("parkBlocker"));SEED = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSeed"));PROBE = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomProbe"));SECONDARY = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSecondarySeed"));} catch (Exception ex) { throw new Error(ex); }}
LockSupport类中有一些核心的线程操作方法,多用于线程的阻塞与唤醒。
调用park()方法使线程阻塞:
public static void park(Object blocker) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, 0L);setBlocker(t, null);}private static void setBlocker(Thread t, Object arg) {// Even though volatile, hotspot doesn't need a write barrier here.UNSAFE.putObject(t, parkBlockerOffset, arg);}
调用park(Object blocker)对传入的线程进行阻塞
public static void park(Object blocker) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, 0L);setBlocker(t, null);}
在截止时间之前阻塞传入的某个线程:
public static void parkUntil(Object blocker, long deadline) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(true, deadline);setBlocker(t, null);}
在nanos的时间范围内阻塞传入的线程:
public static void parkNanos(Object blocker, long nanos) {if (nanos > 0) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, nanos);setBlocker(t, null);}}
唤醒传入的线程:
public static void unpark(Thread thread) {if (thread != null)UNSAFE.unpark(thread);}

wait/notify方法和park/unpark方法区别
LockSupport类中的方法还有很多,在此先列举到这里。当我们看到阻塞和唤醒方法时,我们会联想到另一组唤醒方法wait()和notify(),这两组方法还是有所区别的。
这里直接记录下结论:wait和notify方法只能在同步代码块中使用(即必须与synchronized连用);必须先执行wait方法,然后再执行notify方法唤醒线程,调换顺序的话线程仍处于阻塞状态。
而park()和unpark()方法与之不同,这里可以通过代码运行结果来看:
package XIAOWEI;
import java.util.concurrent.locks.LockSupport;public class Xiaowei{public static void main(String[] args) {Thread A = new Thread(()-> {System.out.println("线程A已经被阻塞QWQ");LockSupport.park();System.out.println("线程A被线程B唤醒啦~~~");});A.start();new Thread(()->{System.out.println("线程B在唤醒线程A ing~~~");LockSupport.unpark(A);},"B").start();}
}

那如果我们先通过线程B唤醒线程A,然后再让线程A阻塞呢(让线程A的阻塞休眠两秒)?
package XIAOWEI;
import java.util.concurrent.locks.LockSupport;
public class Xiaowei {public static void main(String[] args) {Thread A = new Thread(()-> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程A已经被阻塞QWQ(第二版)");LockSupport.park();System.out.println("线程A被线程B唤醒啦~~~(第二版)");});A.start();new Thread(()->{System.out.println("线程B在唤醒线程A ing~~~驾驾驾");LockSupport.unpark(A);},"B").start();}
}

由上面输出结果来看,虽然线程B先唤醒了线程A,然后线程A再开始阻塞,但是线程A还是处于唤醒状态,这是为什么呢?
接下来我找了段LockSupport类中的注释,其实有时看看注释也挺有意思的哈哈:
* <p>This class associates, with each thread that uses it, a permit* (in the sense of the {@link java.util.concurrent.Semaphore* Semaphore} class). A call to {@code park} will return immediately* if the permit is available, consuming it in the process; otherwise* it <em>may</em> block. A call to {@code unpark} makes the permit* available, if it was not already available. (Unlike with Semaphores* though, permits do not accumulate. There is at most one.)
这段话大意是说,LockSupport类使用permits这个东西来实现线程的阻塞和唤醒。每一个线程都会使用到(拥有)permit,且permit的值默认为0。接着它又说,这个概念和Semaphore信号量差不多,但是permit的值只有0和1两个值。哦~原来是这样。
对于上面例子,线程B调用unpark方法唤醒A后,会使得线程A的permit值为1,当线程调用park方法使自己阻塞时,发现自己已经有许可(permit)了,就会继续向下执行业务,而不会阻塞不动。

好了,本篇文章就先分享到这里了,后续会继续分享其他方面的知识,感谢大佬认真读完支持咯~

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起讨论😁
希望能和诸佬们一起努力,今后我们顶峰相见🍻
再次感谢各位小伙伴儿们的支持🤞

相关文章:
LockSupport常用方法源码分析
前言:本文将介绍LockSupport类中的方法和部分源码,以及面试常问到的一个小问题,感兴趣的大佬可以指点下。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们😉😉。 如果文章有什么需要改进的地方还请大佬不吝赐教&am…...
Mybatis Notes
文章目录1 Mybatis 介绍1.1 快速入门2 JDBC2.1 JDBC介绍2.3 JDBC问题分析2.4 Mybatis与JDBC技术对比3 数据库连接池3.1 数据库连接池介绍3.2 数据库连接池产品产品3.3 Druid引入项目4lombok4.1 lombok介绍4.2 lombok使用4.2.1 在pom.xml文件中引入依赖4.2.2 pojo类代码引入1 My…...
MySQL 10:MySQL事务
MySQL 中的事务是由存储引擎实现的。在 MySQL 中,只有 InnoDB 存储引擎支持事务。事务处理可用于维护数据库的完整性,确保批处理的 SQL 语句要么执行要么根本不执行。事务用于管理 DDL、DML 和 DCL 操作,例如插入、更新和删除语句,…...
软件设计(十三)-原码、反码、补码、移码
软件设计(十二)数据结构(下)https://blog.csdn.net/ke1ying/article/details/129035300 下面把一个数转成二进制表达形式 原码: 数值1 : 0000 0001 数值-1 : 1000 0001 1 (- 1) : 1000 0010 这是8个…...
5.4 BGP地址聚合
5.3.1配置BGP地址聚合 1. 实验目的 熟悉BGP地址聚合的应用场景掌握BGP地址聚合的配置方法2. 实验拓扑 实验拓扑如图5-4所示: 图5-4:配置BGP地址聚合 3. 实验步骤 (1)配置IP地址 R1的配置 <Huawe…...
华为OD机试 - 数列还原(Python) | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】 华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】 华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】 华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 …...
华为OD机试题 - 新工号系统(JavaScript)| 代码+思路+重要知识点
最近更新的博客 华为OD机试题 - 字符串加密(JavaScript) 华为OD机试题 - 字母消消乐(JavaScript) 华为OD机试题 - 字母计数(JavaScript) 华为OD机试题 - 整数分解(JavaScript) 华为OD机试题 - 单词反转(JavaScript) 使用说明 参加华为od机试,一定要注意不要完全背…...
Java-算法竞赛中常用的Java API之大数类
Java-算法竞赛中常用的Java API之大数类摘要BigInteger和BigDecimal创建赋值加法减法乘法除法*取余*求最大公因数求最值*(a^b)%mod比较大小*进制转化类型转化BigDecimal精度问题保留n位小数摘要 java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1, 对应的十进制数是92…...
了解Nginx,这一篇就够了
了解Nginx,这一篇就够了1.Nginx应用场景2.Nginx相关概念正向代理和反向代理负载均衡动静分离3.Nginx配置文件解析全局块events块http块1.Nginx应用场景 HTTP服务器:Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可…...
k8s删除pod或deployment
查看pod或者deployment信息 deployment: kubectl get deployment -n 命名空间pod: kubectl get pod -n 命名空间删除pod或者deployment 删除pod: kubectl delete pod <pod名> -n <命名空间>可是,此时你会发现刚刚…...
Visual Studio 2022: 增加对虚幻引擎的支持
自 Visual Studio 2022 发布以来,我们一直专注于为游戏和大型项目开发人员提供一系列生产力和性能改进。今天,我们很高兴与大家分享下一组专门用来提高虚幻引擎开发效率的功能。我们听到并看到了来自你(我们的游戏开发人员)的大量…...
【Python】以邮件的方式定时发送一天的股票分析报告
【Python】以邮件的方式定时发送一天的股票分析报告 文章目录【Python】以邮件的方式定时发送一天的股票分析报告1、Python发送邮件1)EmailSender封装2)可能存在的问题2、jinja2动态渲染html页面3、阿里云OSS搭建图床1)Python上传图片到OSS中…...
mybatis条件构造器(二)
mybatis条件构造器(二) 1 准备工作 1.1 建表sql语句(Emp表) SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for emp -- ---------------------------- DROP TABLE IF EXISTS emp; CREATE TABLE emp (EMPNO int NOT NU…...
C++【类与对象】
文章目录类与对象(1)类与对象一1.0.面向过程和面向对象初步认识1.1.类的引入1.2.类的定义1.3.类的访问限定符及封装1.4.类的作用域1.5.类的实例化1.6.类的对象大小的计算1.8.类成员函数的this指针(2)类与对象二2.0类的6个默认成员…...
假设检验选择统计量重点-----正态总体参数的假设检验
文章目录单个正态总体参数的假设检验单个正态总体N(μ,σ2)N(\mu,\sigma^2)N(μ,σ2)的均值μ\muμ的假设检验1.σ2\sigma^2σ2已知(U检验法)单个正态总体方差的假设检验单边检验简介--计算拒绝域两个正态总体参数的假设检验方差已知的两正态总体均值的假设检验均值未知的两正态…...
华为OD机试 - 通信误码(Python) | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】 华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】 华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】 华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 …...
设计模式之装饰者模式
文章の目录一、什么是装饰者模式二、优势三、缺点四、应用场景五、示例参考写在最后一、什么是装饰者模式 装饰者模式也称为包装器模式,在不改变原有对象的基础上为其动态的添加上新的功能。 装饰者模式有以下特点: 添加功能时不改变原对象结构。装饰…...
【第31天】SQL进阶-写优化- 插入优化(SQL 小虚竹)
回城传送–》《31天SQL筑基》 文章目录零、前言一、练习题目二、SQL思路:SQL进阶-写优化-插入优化解法插入优化禁用索引语法如下适用数据库引擎非空表:禁用索引禁用唯一性检查语法如下适用数据库引擎禁用外键检查语法如下适用数据库引擎批量插入数据语法…...
SpringBoot自动装配的原理
前言 在开发SpringBoot项目时,当我们引入spring-boot-starter-xxx依赖后,想要使用依赖中的bean,直接就用Autowired拿来用了,不需要用xml或者注解的方式把它先注入到Spring容器中。这就是自动装配的特性,本文来讲述Spri…...
Vue3电商项目实战-分类模块5【12-二级类目-结果区-排序组件、13-二级类目-结果区-数据加载、14-二级类目-结果区-进行筛选】
文章目录12-二级类目-结果区-排序组件13-二级类目-结果区-数据加载14-二级类目-结果区-进行筛选12-二级类目-结果区-排序组件 目的:封装排序组件,完成排序切换效果 大致步骤: 定义一个组件 sub-sort,完成基础布局在 sub.vue 组件…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
