共享模型之管程(六)

news2025/2/25 5:43:23

1.park&unpark

1.1.概述

1>.他们是LockSupport类中的方法

// 暂停当前线程
LockSupport.park(); 

// 恢复某个线程的运行
LockSupport.unpark(暂停线程对象)

注意:先park再unpark!

1.2.案例

@Slf4j
public class TestPark {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            log.info("子线程t1 start...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("子线程t1 park...");
            //子线程暂停在这一行
            //获取对象锁的线程由于某些原因无法继续执行,线程变成WAITING状态
            LockSupport.park();
            log.info("子线程t1 resume");
        }, "t1");
        t1.start();

        //main线程睡眠2s
        Thread.sleep(2000);
        log.info("main线程unPark t1线程");
        //恢复某个被暂停都线程
        LockSupport.unpark(t1);
    }
}

在这里插入图片描述
注意:

当前程序中先在子线程中执行park()暂停子线程的执行,然后再在main线程中执行unpark()恢复暂停执行的线程,最终结果一切正常,但是如果是先在main线程中执行unpark()恢复某个暂停执行的线程,然后再在子线程中执行park()暂停子线程的执行,那么结果会怎样呢?答案是一切正常!

@Slf4j
public class TestPark {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            log.info("子线程t1 start...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("子线程t1 park...");
            //子线程暂停在这一行
            //获取对象锁的线程由于某些原因无法继续执行,线程变成WAITING状态
            LockSupport.park();
            log.info("子线程t1 resume");
        }, "t1");
        t1.start();

        //main线程睡眠1s
        Thread.sleep(1000);
        log.info("main线程unPark t1线程");
        //恢复某个被暂停都线程
        LockSupport.unpark(t1);
    }
}

在这里插入图片描述
结论:

LockSupport.unpark()既可以在LockSupport.park()之前执行,也可以在之后执行,效果都是一样的!

1.3.特点

1>.与Object的wait&notify相比:

①.wait,notify/notifyAll必须配合Object Monitor(对象锁)一起使用,而park/unpark不必;

②.park&unpark是以线程为单位来"阻塞"和"唤醒"线程(即可以明确唤醒某个线程),而notify只能随机唤醒一个等待线程,notifyAll是唤醒所有等待线程,就不那么"精确";

③.park&unpark可以先unpark,而wait&notify不能先notify;

1.4.原理

1>.每个线程都有自己的一个Parker对象,由三部分组成:_counter,_cond和_mutex;

打个比喻:

①.线程就像一个旅人,Parker就像他随身携带的背包,_cond(条件变量)就好比背包中的帐篷._counter就好比背包中的备用干粮(0为耗尽,1为充足),_mutex就是需要进帐篷休息;

②.调用park()就是要看需不需要停下来歇息:

  • 如果备用干粮耗尽,那么钻进帐篷歇息;
  • 如果备用干粮充足,那么不需停留,继续前进;

③.调用unpark(),就好比补充干粮:

  • 如果这时线程还在帐篷,就唤醒让他继续前进(子线程首先执行park()处于暂停状态);
  • 如果这时线程还在运行,那么下次他调park()时,仅是消耗掉备用干粮(unpark增加的备用干粮),不需停留而继续前进(先执行unpark(),然后子线程再执行park());

注意:因为背包空间有限,多次调用unpark()仅会补充一份备用干粮!

2>.原理图

在这里插入图片描述
①.当前线程Thread_0先调用Unsafe.park()方法;
②.检查_counter,本情况为0,这时,获得_mutex互斥锁;
③.当前线程Thread_0进入_cond条件变量阻塞(WAITING);
④.设置_counter=0;


在这里插入图片描述
①.其他线程之后再调用Unsafe.unpark(Thread_0)方法,设置_counter为1;
②.唤醒_cond条件变量中的Thread_0线程;
③.Thread_0线程恢复运行;
④.设置_counter为0;


在这里插入图片描述
①.其他线程先调用Unsafe.unpark(Thread_0)方法,设置_counter为1;
②.当前线程Thread_0调用Unsafe.park()方法;
③.检查_counter,本情况为1,这时线程Thread_0无需阻塞,继续运行;
④.最后设置_counter为0;

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

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

相关文章

持续数据保护(CDP)适合档案数据备份吗?

几个月前笔者写过两篇针对档案长期保存库备份(或者说是档案数字资源长期保存策略)的文章,《电子档案备份相对于数据备份的特别之处》、《备份策略从“3-2-1”到“4-3-2-1”》,但是很多读者依然觉得不解渴,因为目前绝大…

Activity和Fragment的生命周期总结以及保存实例状态机制

读完将收获以下内容 一. Activity的生命周期详解 Activity配置和状态改变时生命周期 Activity状态和配置改变时的解决方案 二.Fragment的生命周期详解 Fragment配置和状态改变时生命周期 Fragmen状态和配置改变时的解决方案 三.Activity和Fragment的生命周期调用顺序 一. Acti…

笔记--Qt Pro语法总结

QT pro文件: 任何一个 Qt 项目都至少包含一个 pro 文件,此文件负责存储与当前项目有关的配置信息,比如: 项目中用到了哪些模块? 项目中包含哪些源文件,哪些头文件,它们的存储路径是什么&…

德育知识元素挖掘系统设计 软件工程 spring boot + Vue.js + python机器学习

第一章 绪论 摘要 当今社会发展迅速,机器学习相关技术快速在各行各业普及,制作数据挖掘系统的需求日益增长。同时,随着社会发展不断推进,对学生进行德育教育的规模越做越大,成为了教育行业发展的一大趋势。对于较大规模…

glibc 2.31 pwn——house of pig原题分析与示例程序

house of pig这种利用方式来源于XCTF 2021 final中的同名题,其原题使用的是libc 2.31版本,本文就根据这道题学习一下这种漏洞利用方式。 参考资料 这是一道C pwn,但漏洞本身与C不同于C的特性关系不大。 一共提供了5个选项: 增&…

idea无法安装插件

不能安装插件,首先需要确定是问题,最常见的是无法下载和安装不上, 1.无法下载解决版本 无法下载很多时候就是延迟太高导致的,我们先打开插件官网看一下 Python - IntelliJ IDEs Plugin | Marketplace 如果网站无法打开&#xf…

【测试】用例篇

努力经营当下,直至未来明朗! 文章目录一、设计测试用例的万能公式二、设计测试用例的具体方法1. 等价类2. 边界值3. 因果图(判定表)4. 场景设计法5. 正交法6. 错误猜测法:sparkles: 小结普通小孩也要热爱生活! 一、设…

JS数据类型判断的九种方式

JS 的数据类型检测是一道经典的八股文面试题。相信大家都能条件反射的回答出 4 种方法:typeof、constructor、instanceof 和 Object.prototype.toString,并且对它们各自的优缺点也是张口就来。 本文对这些方法做了简单归纳,同时又补充了其他…

Leetcode:112. 路径总和、113. 路径总和 II(C++)

目录 112. 路径总和: 问题描述: 实现代码与解析: 递归: 原理思路: 迭代: 原理思路: 113. 路径总和 II: 问题描述: 实现代码与解析: 迭代&#xff…

分享66个NET源码,总有一款适合您

NET源码 分享66个NET源码,总有一款适合您 NET源码下载链接:https://pan.baidu.com/s/1-H0UV3yly3p1PXbeLAvMtA?pwdk06f 提取码:k06f page_count 1 # 每个栏目开始业务content"text/html; charsetgb2312"base_url "http…

go defer return panic 执行顺序

根据代码实例运行结果来总结说明:定义一个函数,有多个defer (用于判断多个defer执行顺序),有panic和 return (判断与defer对比执行顺序)一、函数中有panicpackage mainimport "fmt"fu…

【矩阵论】8. 常用矩阵总结——秩1矩阵,优阵(单位正交阵),Hermite阵

矩阵论 1. 准备知识——复数域上矩阵,Hermite变换) 1.准备知识——复数域上的内积域正交阵 1.准备知识——Hermite阵,二次型,矩阵合同,正定阵,幂0阵,幂等阵,矩阵的秩 2. 矩阵分解——SVD准备知识——奇异值…

【性能调优】【离线任务】flink处理离线任务(8000个小文件?200多亿数据量?)稳定性与性能调优探索

文章目录一、场景描述1. 任务类型描述2. 问题任务二、相关理论1.Task Slots and Resources1.1. slots与资源的隔离和共享1.2 建议cpu和slot数关系2. tm的资源配置是否合适2.1. flink load problems2.2. 阿里 flink资源配置建议三、问题分析与解决1. 测试结果比对1.1. 任务11.2.…

小程序学习(2)-----常用的各类组件

新建项目 项目->新建项目-小程序,如下图所示 新建小程序页面 只需要在 app.json->pages 中新增页面的存放路径,小程序开发者工具可帮我们自动创建对应的页面文件,如图所示: 2.常用的视图容器类组件 ① view 普通视图区域类…

Java基础算法每日5道详解(3)

136. Single Number 单号 Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. You must implement a solution with a linear runtime complexity and use only constant extra space. 给定一个非空整数数组 nu…

在Multisim导入TI提供的SPICE模型

对在multisim中导入TI模型的一个记录。 multisim中只有常规的元器件,对于很多元器件multisim都没有相应的模型,这就需要手动导入了。 Multisim导入模型1、从官网下载相应的模型文件2、在Multisim中导入模型3、写在后面1、从官网下载相应的模型文件 &…

c/c++ 函数(一) setw()、isdigit()、isalpha()、atoi()、itoa()

目录 1、setw(int n) <iomanip> 2、int isdigit(char ch) <ctype.h> 3、int isalpha(int c) <ctype.h> 4、int atoi(const char* str) <stdlib.h> 5、char* itoa(int num) <stdlib.h> 1、se…

Linux 基本权限

目录 1 shell命令以及运行原理 1.1 理解 1.2 意义 2 Linux权限的概念 2.1 概念 2.2 用户分类 2.3 Linux文件属性 2.4 Linux文件权限 2.4.1 文件访问者的分类&#xff08;人&#xff09; 2.4.2 root&&普通用户 vs 拥有者&&所属组&&other 2.4…

异步架构,避免相互依赖的系统耦合

前言&#xff1a; 使用缓存架构可以减少不必要的计算&#xff0c;快速响应用户请求&#xff0c;但是缓存只能改善系统的读操作性能&#xff0c;也就是在读取数据的时候&#xff0c;可以不从数据源中读取&#xff0c;而是通过缓存读取&#xff0c;以加速数据的读取速度。 但是…

vulnhub DC系列 DC-6

总结:wpscan爆破&#xff0c;nmap提权 下载地址 DC-6.zip (Size: 619 MB)Download: http://www.five86.com/downloads/DC-6.zipDownload (Mirror): https://download.vulnhub.com/dc/DC-6.zip使用方法:解压后&#xff0c;使用vm直接打开ova文件。 漏洞分析 信息收集 这里还是使…