【多线程开发 4】从源码学习LockSupport
从源码学习LockSupport
2024年6月30日
大家好啊,好久没写博客了,今天打算写一下,讲一下JUC里面LockSupport这个类。
这个是一个工具类,实际上也是为了线程通信开发的。它的源码比较短,也只引用了Unsafe一个类。所以我们可以先看下他的源码:
类注释
他的类注释如下:
Basic thread blocking primitives for creating locks and other synchronization classes.
This class associates, with each thread that uses it, a permit (in the sense of the Semaphore class). A call to park will return immediately if the permit is available, consuming it in the process; otherwise it may block. A call to unpark makes the permit available, if it was not already available. (Unlike with Semaphores though, permits do not accumulate. There is at most one.) Reliable usage requires the use of volatile (or atomic) variables to control when to park or unpark. Orderings of calls to these methods are maintained with respect to volatile variable accesses, but not necessarily non-volatile variable accesses.
Methods park and unpark provide efficient means of blocking and unblocking threads that do not encounter the problems that cause the deprecated methods Thread. suspend and Thread. resume to be unusable for such purposes: Races between one thread invoking park and another thread trying to unpark it will preserve liveness, due to the permit. Additionally, park will return if the caller’s thread was interrupted, and timeout versions are supported. The park method may also return at any other time, for “no reason”, so in general must be invoked within a loop that rechecks conditions upon return. In this sense park serves as an optimization of a “busy wait” that does not waste as much time spinning, but must be paired with an unpark to be effective.
The three forms of park each also support a blocker object parameter. This object is recorded while the thread is blocked to permit monitoring and diagnostic tools to identify the reasons that threads are blocked. (Such tools may access blockers using method getBlocker(Thread).) The use of these forms rather than the original forms without this parameter is strongly encouraged. The normal argument to supply as a blocker within a lock implementation is this.
These methods are designed to be used as tools for creating higher-level synchronization utilities, and are not in themselves useful for most concurrency control applications. The park method is designed for use only in constructions of the form:while (!canProceed()) { // ensure request to unpark is visible to other threads ... LockSupport. park(this); }where no actions by the thread publishing a request to unpark, prior to the call to park, entail locking or blocking. Because only one permit is associated with each thread, any intermediary uses of park, including implicitly via class loading, could lead to an unresponsive thread (a “lost unpark”).
Sample Usage. Here is a sketch of a first-in-first-out non-reentrant lock class:class FIFOMutex {private final AtomicBoolean locked = new AtomicBoolean(false);private final Queue<Thread> waiters = new ConcurrentLinkedQueue<>();public void lock() {boolean wasInterrupted = false;// publish current thread for unparkerswaiters.add(Thread.currentThread());// Block while not first in queue or cannot acquire lockwhile (waiters.peek() != Thread.currentThread() || !locked.compareAndSet(false, true)) {LockSupport.park(this);// ignore interrupts while waiting if (Thread.interrupted()) wasInterrupted = true;}waiters.remove();// ensure correct interrupt status on returnif (wasInterrupted)Thread.currentThread().interrupt();}public void unlock() {locked.set(false);LockSupport.unpark(waiters.peek());}static { // Reduce the risk of "lost unpark" due to classloadingClass<?> ensureLoaded = LockSupport.class;} }
第一段文本大意为:
用于创建锁和其他同步类的基本线程阻塞原语。这个类与使用它的每个线程关联一个许可证(在信号量类的意义上)。如果许可证可用,将立即返回停车呼叫,并在此过程中消耗许可证;否则可能会堵塞。如果许可证尚未可用,则调用取消停车使其可用。(但与信号量不同的是,许可证不会累积。最多只有一个。)可靠的使用需要使用易失性(或原子)变量来控制何时停放或取消停放。调用这些的顺序
其实就是对想要枷锁的信息加上一个许可,提前给他许可再消费许可,还是代码走到消费许可后再拿到许可都可以,。
第二段文本大意为:
如果在调用park之前,线程没有发布请求取消park的操作,则会导致锁定或阻塞。因为每个线程只关联一个许可证,任何中间使用park(包括通过类加载隐式地使用)都可能导致线程无响应(“丢失的unpark”)。
样品使用。这是一个先进先出的不可重入锁类的草图:
就是根据第二块代码展示LockSupport具体怎么使用。
代码细节
unpark(Thread thread)
给对应thread发放许可。如果线程被LocjSupport的park()方法阻塞时,使用该方法会被立刻释放运行,如果没有阻塞,则使用该方法发放许可证明时,在下一次调用park()方法,则会直接运行不被阻塞。
park(Object blocker)
会向当前线程请求许可,没有许可就会阻塞,除非发生以下三种情况之一:
- 其他线程以当前线程为目标调用unpark
- 其他线程中断当前线程
- 调用返回
但是park方法不能看出来是哪一个原因导致线程可以重新运行。需要调用的人自己写代码看,例如,线程返回时的中断状态。
parkNanos(Object blocker, long nanos)
和park方法一样,但是有时间限制,到了时间限制也会停止阻塞。
getBlocker(Thread t)
提供阻塞线程t的正在被阻塞的park方法是谁调用的,但是线程不安全,拿到这个对象操作的时候可能也已经被unpark了也说不定。
park()
直接禁用当前线程。
private LockSupport() {} // Cannot be instantiated.
LockSupport不能被初始化,只能使用LockSupport进行开发
setCurrentBlocker(Object blocker)
该方法可以做到在blocker使用park()方法之前会调用该方法,可以做到一些分析的作用。
总结
这个方法比较简单,但是比较方便进行线程间通信。
相关文章:
【多线程开发 4】从源码学习LockSupport
从源码学习LockSupport 2024年6月30日 大家好啊,好久没写博客了,今天打算写一下,讲一下JUC里面LockSupport这个类。 这个是一个工具类,实际上也是为了线程通信开发的。它的源码比较短,也只引用了Unsafe一个类。所以…...
gameui C++的代码
gameui C的代码 #include <graphics.h> #include "gameboard.h" const int WIDTH 560; const int HEIGHT 780; const int GRID_SIZE 120; class GameUi { private: public:GameUi(GameBoard& gb) {// 初始化图形窗口initgraph(WIDTH, HEIGHT);// 设置…...
1.什么是js?特点是什么?组成部分?
Js是一种直译式脚本语言,一种动态类型,弱类型,基于原型的高级语言。 直译式:js程序运行过程中直接编译成机器语言。 脚本语言:在程序运行过程中逐行进行解释说明,不需要预编译。 动态类型:js…...
爬虫是什么?
目录 1.什么是互联网爬虫? 2.爬虫核心? 3.爬虫的用途? 4.爬虫分类? 5.反爬手段? 1.什么是互联网爬虫? 如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序…...
深入理解Presto分页查询:方法与最佳实践
目录 引言为什么需要分页查询Presto简介分页查询的基本概念Presto分页查询的实现方法 使用LIMIT和OFFSET使用游标分页结合外部工具和框架 分页查询的性能优化 索引优化查询计划优化数据分区 实际案例分析最佳实践与常见问题 大数据集分页复杂查询分页实时性要求高的场景 总结 …...
如何使用Go语言中的并发函数实现网络爬虫的分布式部署?
如何使用go语言中的并发函数实现网络爬虫的分布式部署? 在当今的互联网时代,大量的信息蕴藏在各个网站中,爬虫成为了一种重要的工具。而对于大规模的数据爬取任务,采用分布式部署能够更有效地提升爬取速度和效率。Go语言的并发机…...
STM32第九课:DHT11温湿度传感器
文章目录 需求一、DHT11温湿度传感器二、模块配置流程1.配置时钟和IO2.读取数据3.数据处理 三、导入语音模块四、关键代码总结 需求 1.完成DHT11温湿度检测模块的配置。 2.处理DHT11获取的数据,在串口打印处理后的实时数据。 2.通过Su-03t语音识别模块实现实时温湿…...
JVM线上监控环境搭建Grafana+Prometheus+Micrometer
架构图 一: SpringBoot自带监控Actuator SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控内存状况、CPU、Bean加载情况、配置属性、日志信息、线程情况等。 使用步骤: 1. 导入依赖坐标 <dependency><…...
MyBatis(17)MyBatis 如何处理枚举类型
MyBatis 处理枚举类型的机制相对直接,它提供了一种灵活的方式来处理Java枚举(enum)类型和数据库之间的映射。在MyBatis中,你可以通过两种方式处理枚举类型:使用枚举的名称(name)或者枚举的序号&…...
云数据中心运维新纪元:让Linux服务器如虎添翼
文章目录 一、Linux系统管理的高级技巧1. 性能调优与监控:2. 自动化与脚本编写:3. 文件系统与存储管理: 二、服务器配置优化的策略1. 硬件选型与配置:2. 网络配置与优化:3. 应用部署与调优: 三、安全策略的…...
C# 多线程造成CPU占用率高
当线程多的时候就会造成CPU内存占用率过高 private void button1_Click(object sender, EventArgs e){Thread TH1, TH2, TH3, TH4, TH5;TH1 new Thread(Thread1){IsBackground true};TH2 new Thread(Thread2){IsBackground true};TH3 new Thread(Thread3){IsBackground t…...
谈谈在不同公司中的SAP职位
今天反客为主,聊一下这个HR的话题,考虑到SAP职位的专业性,感觉还是有必要谈一谈这个话题。最近跟几位HR的小伙伴聊了一下,讨论了下不同公司的SAP职位的招聘要求,感觉还是有那么几个存在的问题: 追求完美的…...
服务器连接不上
记录今天2024/07/02的问题: 我今天真的是非常无语,今天在连服务器的时候,突然发现连不上了。 后来才意识到,原来是我笔记本先是开了全局代理,然后再用easy connected连接。当时还跳出了一个窗口如下,我当时…...
论文辅导 | 基于贝叶斯优化-卷积神经网络-双向长短期记忆神经网络的锂电池健康状态评估
辅导文章 模型描述 准确估计电池健康状态是设备稳定运行的关键。针对当前健康状态研究中容量难以直接测量、估计模型调参费时等问题,提出基于多健康特征的贝叶斯优化(BO)算法优化卷积神经网络(CNN)与双向长短期记忆&a…...
安卓实现微信聊天气泡
一搜没一个能用的,我来: 布局文件: <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xml…...
软件测试(功能、接口、性能、自动化)详解 | 测试人生路
一、软件测试功能测试 测试用例编写是软件测试的基本技能;也有很多人认为测试用例是软件测试的核心;软件测试中最重要的是设计和生成有效的测试用例;测试用例是测试工作的指导,是软件测试的必须遵守的准则。 黑盒测试常见测试用…...
【面试题】网络IO模型
IO(Input/Output)模型指的是计算机系统中对输入/输出操作进行处理的不同方式。它定义了操作系统内核、应用程序和I/O设备之间如何交互和协调数据传输。不同的IO模型在效率、复杂性和适用场景方面都有所差异。以下是几种主要的IO模型及其特点:…...
数据结构-----【链表:基础】
链表基础 1、链表的理论基础 1)基础: 链表:通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个指针…...
如何在pycharm里面运行pytest用例
pycharm运行三种方式 1.以xx.py脚本方式直接执行,当写的代码里面没用到unittest和pytest框架时,并且脚本名称不是以test_开头命名的,此时pycharm会以xx.py脚本方式运行 2.当脚本命名为test_xx.py时,用到unittest框架,…...
Charles抓包工具踩坑记录
请添加图片描述 Charles抓包工具 证书问题 输入网址:chls.pro/ssl 第一个下载证书网址,会出现一直加载不出来,无法下载证书的情况 解决:选择下面save Charles Root。。。 2 证书在mac中禁止修改问题 解决也很简单,按照…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
