多线程学习篇六:park / unpark

news2024/11/7 9:38:54

1. API

  • LockSupport.park():暂停当前线程
  • LockSupport.unpark (线程对象):恢复某个线程的运行

1.1 先 park 再 unpark

main 线程睡眠时间大于 t1 线程睡眠时间

@Slf4j(topic = "c.Test01")
public class Test01 {

    public static void main(String[] args) throws Exception {

        Thread t1 = new Thread(() -> {
            log.info("start...");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("park...");
            LockSupport.park();

            log.info("resume...");
        }, "t1");
        t1.start();

        TimeUnit.SECONDS.sleep(2);

        log.info("unpark... ");
        LockSupport.unpark(t1);
    }
}

通过运行结果得出结论:阻塞的线程在执行 unpark 方法后,恢复运行

1.2 先 unpark 再 park

main 线程睡眠时间小于 t1 线程睡眠时间

@Slf4j(topic = "c.Test01")
public class Test01 {

    public static void main(String[] args) throws Exception {

        Thread t1 = new Thread(() -> {
            log.info("start...");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("park...");
            LockSupport.park();

            log.info("resume...");
        }, "t1");

        t1.start();

        TimeUnit.SECONDS.sleep(1);

        log.info("unpark... ");
        LockSupport.unpark(t1);
    }
}

通过运行结果得出结论:如果 t1 线程在执行 park 方法之前执行了 unpark 方法,park 方法不能让 t1 线程进入阻塞状态

1.3 执行多次 unpark 再 park

@Slf4j(topic = "c.Test02")
public class Test02 {

    public static void main(String[] args) throws Exception {

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        Thread t1 = new Thread(() -> {
            log.info("start...");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("park1...");
            LockSupport.park();

            log.info("park2...");
            LockSupport.park();

            log.info("resume...");
        }, "t1");
        t1.start();

        TimeUnit.SECONDS.sleep(1);

        log.info("unpark : " + LocalDateTime.now().format(dateTimeFormatter));
        LockSupport.unpark(t1);

        log.info("unpark : " + LocalDateTime.now().format(dateTimeFormatter));
        LockSupport.unpark(t1);

        TimeUnit.SECONDS.sleep(3);

        log.info("unpark : " + LocalDateTime.now().format(dateTimeFormatter));
        LockSupport.unpark(t1);
    }
}

通过运行结果得出结论:如果 t1 线程在执行 park 方法之前执行了多次 unpark 方法,第一次执行 park 方法不进入阻塞状态,再一次执行 park 方法将进入阻塞状态

1.4 小结

  • 如果一个运行的线程在执行 park 方法之前,未执行 unpark 方法,线程进入阻塞状态
  • 如果一个运行的线程在执行 park 方法之前,执行了一次或多次 unpark 方法,线程不进入阻塞状态,而是继续向下运行

2. park & unpark 与  wait & notify & notifyAll 的区别

  • wait & notify & notifyAll 需要和 synchronized 关键字一起使用,而 park & unpark 不需要
  • park & unpark 会阻塞(唤醒 )指定线程,而 notify 只能随机唤醒一个等待线程,notifyAll 唤醒所有等待线程
  • park & unpark 可以先 unpark 再 park,给线程一次 “免阻塞” 的机会,而 wait & notify & notifyAll 不可以

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

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

相关文章

计算机网络:网络层 —— IPv4 数据报的首部格式

文章目录 IPv4数据报的首部格式IPv4数据报分片生存时间 TTL字段协议字段首部检验和字段 IPv4数据报的首部格式 IPv4 数据报的首部格式及其内容是实现 IPv4 协议各种功能的基础。 在 TCP/IP 标准中,各种数据格式常常以32比特(即4字节)为单位来描述 固定部分&#x…

基于SSM演出道具租赁系统的设计

管理员账户功能包括:系统首页,个人中心,用户管理,商家管理,道具类型管理,道具出租管理,租赁订单管理,道具归还管理,系统管理 商家账号功能包括:系统首页&…

《使用Gin框架构建分布式应用》阅读笔记:p272-p306

《用Gin框架构建分布式应用》学习第15天,p272-p306总结,总35页。 一、技术总结 1.TDD(test-driven development) 虽然经常看到TDD这个属于,从本人的工作经历看,实际开发中用得相对较少。 2.unitest(单元测试) go语言开发中&a…

三种SPI机制的了解及使用

文章目录 1.SPI机制概念2.Java SPI2.1 创建一个项目,并创建如下模块2.2 db-api模块2.3 mysql-impl模块2.4 oracle-impl模块2.5 main-project模块 3.Spring SPI4.Dubbo SPI 1.SPI机制概念 SPI全程Service Provider Interface,是一种服务发现机制。 SPI的…

【Linux系统编程】第四十弹---深入理解操作系统:信号捕捉、可重入函数、volatile关键字与SIGCHLD信号解析

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、捕捉信号 1.1、内核如何实现信号的捕捉 1.2、内核态与用户态 1.3.1、用户态(User Space) 1.3.2、…

【面试】数组中 Array.forEach()、Array.map() 遍历结束后是否改变原数组

forEach 、map 同理 数组内元素是 基本数据类型 时, 1.1. 直接给 item赋值,是 不会改变原数组 的(如图中1), 1.2. 通过 原数组索引赋值 是会改变原数组的(如图中2)数组内元素是 复杂数据类型 时…

List<T>属性和方法使用

//author:shark_ddd using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;//使用函数来减少长度namespace List_T {class Student{public string Name { get; set; }public int Age { get; set; …

liunx CentOs7安装MQTT服务器(mosquitto)

查找 mosquitto 软件包 yum list all | grep mosquitto出现以上两个即可进行安装,如果没有出现则需要安装EPEL软件库。 yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm查看 mosquitto 信息 yum info mosquitto安装 mosquitt…

视频去水印软件哪个好?这些软件值得一试

无论是社交媒体上的短视频,还是专业网站上的长视频,去除视频中的水印成为了许多人的需求。 选择一款合适的视频去水印软件,可以帮助我们轻松去除视频中的不必要标记,保持视频的完整性和美观。 那么,视频去水印软件哪…

qt QDoubleSpinBox详解

1、概述 QDoubleSpinBox是Qt框架中的一个控件,专门用于浮点数(即小数)的输入和调节。它提供了一个用户界面元素,允许用户在预设的范围内通过拖动滑块、点击箭头或使用键盘来递增或递减浮点数值。QDoubleSpinBox通常用于需要精确数…

在基于AWS EC2的云端k8s环境中 搭建开发基础设施

中间件下载使用helm,这里部署的都是单机版的 aws-ebs-storageclass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: aws-ebs-storageclass provisioner: kubernetes.io/aws-ebs parameters:type: gp2 # 选择合适的 EBS 类型,如 gp2、io1…

MATLAB与STK互联:仿真并获取低轨卫星与指定区域地面站的可见性数据

MATLAB控制STK实现:仿真并获取低轨卫星与指定区域地面站的可见性数据 本次仿真主要参考了多篇文献和网站,包括但不限于:《Using MATLAB for STK Automation》、CSDN博文: 拜火先知的博客_CSDN博客-笔记、AGI官网有关MATLAB的内容…

docker engine stopped

1)环境:win 10 2)docker安装时已经已经安装了虚拟机 3)启用网络适配器 4)启用docker服务(依赖服务LanmanServer) 5)全都弄好了,docker还是打不开,没办法了&a…

天翼网关 3.0 兆能 ZNHG600 获取超级密码改桥接

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 前不久朋友家断网,喊了宽带师傅修完之后,光猫就从桥接模式变成了路由模式。虽然对于日常上网来说区别不大,但这条宽带有公网 IP,通过光猫拨号的话&#xff0…

C语言常见进制 (二进制、八进制、十进制、十六进制)详解

C语言常见进制的详解 放在最前面的前言:1、分类2、二进制(2.1)二进制的解释说明(2.2)关于二进制的计算(2.3) 二进制转换为八进制(2.4) 二进制转换为十进制 3、八进制&…

在 .NET 8 Web API 中实现 Entity Framework 的 Code First 方法

本次介绍分为3篇文章: 1:.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3:.NET …

初识动态规划(由浅入深)

🤓 动态规划入门与进阶指南 📘 动态规划(Dynamic Programming, DP)是一种非常经典的📐算法方法,特别适合用来解决那些有大量重复计算的问题🌀。它可以将复杂的问题拆分为小问题🧩&a…

【STM32】SD卡

(一)常用卡的认识 在学习这个内容之前,作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解,晕头转向。 SD卡:Secure Digital Card的英文缩写,直译就是“安全数字卡”。一般用于大一些的电子设备比如:电脑、数码相机、AV…

《JVM第5课》虚拟机栈

无痛快速学习入门JVM,欢迎订阅本免费专栏 Java虚拟机栈(Java Virtual Machine Stack,简称JVM栈,又称Java方法栈)是 JVM 运行时数据区的一部分,主要用于支持Java方法的执行。每当一个新线程被创建时&#xf…

Java Executor RunnableScheduledFuture 总结

前言 相关系列 《Java & Executor & 目录》《Java & Executor & RunnableScheduledFuture & 源码》《Java & Executor & RunnableScheduledFuture & 总结》《Java & Executor & RunnableScheduledFuture & 问题》 涉及内容 《…