c# WaitSleepJoin状态的线程如何自动恢复

在 C# 中,线程的 ThreadState.WaitSleepJoin 状态表示线程当前处于等待、睡眠或加入(比如等待锁、等待事件、或者调用 Thread.Sleep 等)。要让一个处于 WaitSleepJoin 状态的线程恢复运行,必须唤醒它或让它不再被阻塞。这通常通过以下几种方式实现:

1. 使用 Monitor.PulseMonitor.PulseAll

如果线程因为 Monitor.Waitlock 等机制而进入等待状态,可以使用 Monitor.PulseMonitor.PulseAll 来唤醒一个或所有等待的线程。

示例:使用 Monitor 来管理线程的等待和唤醒
using System;
using System.Threading;class Program
{private static object _lock = new object();static void Main(){Thread thread = new Thread(WaitingThread);thread.Start();// 主线程睡眠 1 秒钟,然后唤醒等待线程Thread.Sleep(1000);lock (_lock){Console.WriteLine("主线程正在唤醒等待线程");Monitor.Pulse(_lock); // 唤醒一个等待线程}thread.Join(); // 等待子线程结束}static void WaitingThread(){lock (_lock){Console.WriteLine("等待线程正在等待...");Monitor.Wait(_lock); // 使线程进入等待状态Console.WriteLine("等待线程被唤醒");}}
}

在上述代码中,WaitingThread 线程调用 Monitor.Wait 进入 WaitSleepJoin 状态,主线程通过 Monitor.Pulse 唤醒它,恢复线程执行。

2. 使用 ManualResetEventAutoResetEvent

ManualResetEventAutoResetEvent 是两种常用的同步事件,它们可以用于线程间的协调。你可以使用这些类的 Set 方法来唤醒一个或多个等待线程。

  • AutoResetEvent:每次唤醒一个等待线程后,会自动重置为无信号状态。
  • ManualResetEvent:唤醒后需要手动重置,直到调用 Reset
示例:使用 AutoResetEvent
using System;
using System.Threading;class Program
{private static AutoResetEvent _autoResetEvent = new AutoResetEvent(false);static void Main(){Thread thread = new Thread(WaitingThread);thread.Start();// 主线程睡眠 1 秒钟,然后唤醒等待线程Thread.Sleep(1000);Console.WriteLine("主线程正在唤醒等待线程");_autoResetEvent.Set(); // 唤醒等待线程thread.Join(); // 等待子线程结束}static void WaitingThread(){Console.WriteLine("等待线程正在等待...");_autoResetEvent.WaitOne(); // 线程在此等待直到被唤醒Console.WriteLine("等待线程被唤醒");}
}

在上述代码中,WaitingThread 线程调用 _autoResetEvent.WaitOne() 进入等待状态,主线程通过调用 _autoResetEvent.Set() 唤醒它。

3. 使用 Thread.Sleep

如果线程处于 Thread.Sleep 状态(也是 WaitSleepJoin 状态的一种),它会在设定的时间到达后自动恢复。调用 Thread.Sleep 后的线程会在指定的时间过后继续执行,自动恢复。

示例:使用 Thread.Sleep
using System;
using System.Threading;class Program
{static void Main(){Thread thread = new Thread(WaitingThread);thread.Start();// 主线程睡眠 1 秒钟Thread.Sleep(1000);thread.Join(); // 等待子线程结束}static void WaitingThread(){Console.WriteLine("等待线程正在睡眠...");Thread.Sleep(2000); // 线程睡眠 2 秒Console.WriteLine("等待线程被唤醒");}
}

在上述代码中,WaitingThread 线程调用 Thread.Sleep(2000) 进入等待状态。线程会在 2 秒后自动恢复并继续执行。

4. 使用 Task 类的异步操作

在现代 C# 开发中,使用 Taskasync/await 模式来处理线程等待和恢复是更常见的做法。Task.Delay 使得线程可以在异步等待期间不阻塞主线程。

示例:使用 Task.Delay(异步)
using System;
using System.Threading.Tasks;class Program
{static async Task Main(){Task task = WaitingTask();// 主线程继续执行其他操作await Task.Delay(1000); // 主线程延时 1 秒await task; // 等待任务完成}static async Task WaitingTask(){Console.WriteLine("等待任务正在等待...");await Task.Delay(2000); // 异步等待 2 秒Console.WriteLine("等待任务被唤醒");}
}

在此代码中,WaitingTask 异步任务使用 Task.Delay(2000) 进入等待状态,自动恢复。

总结

要让处于 WaitSleepJoin 状态的线程恢复,可以根据实际情况选择不同的同步机制:

  1. 使用 Monitor.PulseMonitor.PulseAll:用于 lock 语句块中,通过唤醒等待的线程。
  2. 使用 AutoResetEventManualResetEvent:线程等待这些事件的信号来恢复。
  3. 使用 Thread.Sleep:线程会在指定时间后自动恢复执行。
  4. 使用 Task.Delay:异步任务会在指定时间后自动恢复。

通常,现代 C# 开发推荐使用 Taskasync/await 模式来避免复杂的线程管理。

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

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

相关文章

初学stm32---高级定时器输出n个pwm波

目录 高级定时器简介:(F1) 高级定时器框图 重复计数器特性 高级定时器输出指定个数PWM实验原理 高级定时器输出指定个数PWM实验配置步骤 相关HAL库函数介绍 关键结构体介绍 高级定时器简介:(F1) 1.高级定时器 :TIM1/TIM8 2.主要特性&…

【每日学点鸿蒙知识】Shape描述、全局loading组件、checkbox样式、H5监听键盘收起、弹窗不关闭

1、HarmonyOS 有没有xml描述的Shape? 有没有xml描述的Shape? 官方文档有对用的Shape的参考文档,参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-drawing-components-shape-V5 绘制组件的父…

完整的 FFmpeg 命令使用教程

FFmpeg 是一个开源的跨平台音视频处理工具,它能够处理几乎所有的视频、音频格式,并提供了强大的功能如格式转换、视频剪辑、合并、提取音频等。FFmpeg 通过命令行界面(CLI)操作,尽管有一些图形界面的前端工具&#xff…

Mono里运行C#脚本5—mono_file_map_open

前面介绍了mono_jit_init初始化,这个函数非常长,要理解起来还是比较困难。因此改变另外一种方式,先从底层的函数开始,再慢慢来探索mono的底层实现,以及它的实现原理,运行的细节。 Mono要运行exe文件,这里是运行test-embed.exe文件,那么就得认识这个文件,解释这个文件的…

【MySQL】踩坑笔记——保存带有换行符等特殊字符的数据,需要进行转义保存

问题描述 从DBeaver中导出了部分业务数据的 insert sql,明明在开发、测试环境都可以一把执行通过,却在预发环境执行前的语法检查失败了,提示有SQL语法错误。 这条SQL长这样,default_sql是要在odps上执行的sql语句,提…

matlab中的cell

在MATLAB中,cell 是一种非常重要的数据类型,它能够存储不同类型和大小的数据,这使得它非常灵活,适用于处理复杂的数据结构。 1. 基本介绍 cell 类型的变量可以存储不同类型的数据,如数值、字符、结构体、甚至其他的 …

GPU 进阶笔记(二):华为昇腾 910B GPU

大家读完觉得有意义记得关注和点赞!!! 1 术语 1.1 与 NVIDIA 术语对应关系1.2 缩写2 产品与机器 2.1 GPU 产品2.2 训练机器 底座 CPU功耗操作系统2.3 性能3 实探:鲲鹏底座 8*910B GPU 主机 3.1 CPU3.2 网卡和网络3.3 GPU 信息 3.3…

Excel中一次查询返回多列

使用Excel或wps的时候,有时候需要一次查询返回多列内容,这种情况可以选择多次vlookup或者多次xlookup,但是这种做法费时费力不说,效率还有些低下,特别是要查询的列数过多时。我放了3种查询方法,效果图&…

网络基础入门到深入(2):网络协议-TCP/IP协议栈

目录 一.TCP/IP协议栈的四层结构 二.每一层的作用与协议 1.作用层 作用: 常见协议: 示例: 2.传输层 作用: 核心功能: 3.网络层 作用: 核心功能: 常见协议: 示例: 4.数据链路层(物理层) 作用: 核心功能: 常见技术: 示例: 三.TCP/IP协议栈的分层…

C语言 练习

1.按顺序打印三个数 //按大小顺序打印三个数字 void Swap(int* px, int* py) {int tmp *px;*px *py;*py tmp; } int main() {int a 0;int b 0;int c 0;scanf("%d %d %d", &a, &b, &c);if (a < b){Swap(&a,&b);}if (a < c){Swap(&am…

爱思唯尔word模板

爱思唯尔word模板 有时候并不一定非得latex https://download.csdn.net/download/qq_38998213/90199214 参考文献书签链接

flask后端开发(3):html模板渲染

目录 渲染模板html模板获取路由参数 gitcode地址&#xff1a; https://gitcode.com/qq_43920838/flask_project.git 渲染模板 这样就能够通过html文件来渲染前端&#xff0c;而不是通过return了 html模板获取路由参数

Spring发布-订阅模式:解耦与异步通信的高效实现

文章目录 前言一、发布订阅模式的基本概念二、发布订阅模式的实现1、定义事件2、发布事件3、订阅事件3.1、ApplicationListener接口3.2、EventListener注解3.3、事件源Object source的作用 三、开发应用场景1、社交网络平台2、电商系统3、金融交易系统 总结 前言 Spring框架通过…

配置hive支持中文注释

hive元数据metastore默认的字符集是latin1&#xff0c;所以中文注释会乱码。但是不能将metastore库的字符集更改为utf-8&#xff0c;只能对特定表、特定列修改为utf-8。配置hive支持中文注释&#xff0c;主要在两个方面&#xff1a; 1、在Hive元数据存储的Mysql数据库中&#…

python实战案例笔记:统计出数据中路劲下没有文件的文件夹

数据样例&#xff1a;&#x1f447;有如下excel数据 需求&#xff1a;有如下excel&#xff0c;a.xls&#xff0c;统计出路劲下没有文件的路劲 详细实现代码&#xff1a; import os from openpyxl import Workbook from datetime import datetimedef get_empty_dirs(paths):# …

docker使用国内镜像

可用地址 https://docker.m.daocloud.io https://docker.rainbond.cc https://docker.1ms.run方法1:配置(需要重启docker) sudo vim /etc/docker/daemon.json # 在registry-mirrors中添加地址(没有的就直接创建了) #比如 {"registry-mirrors": ["https://dock…

机械臂的各种标定

文章目录 1. 工具坐标系标定2. 工具手标定3. 手眼标定联系 在工程中&#xff0c;同时使用工具坐标系标定、工具手标定和手眼标定的概念、目的和作用如下&#xff1a; 1. 工具坐标系标定 概念&#xff1a; 工具坐标系标定是指确定工具相对于机器人坐标系的位置和姿态关系的过程…

Oracle Managed Files(OMF)

Oracle Managed Files 是指&#xff1a; 在创建表空间文件等文件时&#xff0c;可以不必指定文件路径&#xff0c;由Oracle自动在某个目录下创建&#xff0c;文件名也是Oracle自动命名。 那这个OMF怎么使能呢&#xff1f; 其实是靠设置一些参数&#xff0c;指定要存储的目录…

GXUOJ-算法-第一次作业(整数划分、汉诺塔、排列问题、数塔问题)

1.整数划分 问题描述 GXUOJ | 整数划分 题解 #include<bits/stdc.h> using namespace std; const int N1010,mod1e97;int n; int f[N];int main(){cin>>n;f[0]1;for(int i1;i<n;i){for(int ji;j<n;j){f[j](f[j]f[j-i])%mod;}}cout<<f[n]; } 2.汉诺塔…

新服务器ubuntu系统相关操作

1、查看驱动:驱动版本535.216.01能够支持cuda12.2,下面直接使用默认安装的cuda。 2、赋予用户管理员权限。 首先有超级用户(root)权限来编辑 /etc/sudoers 文件,visudo 是一个命令,用于安全地编辑 /etc/sudoers 文件。运行: sudo visudo 在 visudo 编辑器中,找到类似…