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

news2024/12/27 19:35:03

在 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.coloradmin.cn/o/2266559.html

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

相关文章

flask后端开发(2):URL与视图

目录 URL定义request获取请求参数 gitcode地址: https://gitcode.com/qq_43920838/flask_project.git URL定义 from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello World!app.route(/profile) def profile():return 我是个人…

<数据集>风力发电机损伤识别数据集<目标检测>

数据集下载链接 <数据集>风力发电机损伤识别数据集<目标检测>https://download.csdn.net/download/qq_53332949/90187097数据集格式:VOCYOLO格式 图片数量:2527张 标注数量(xml文件个数):252…

【工具推荐】MobaXterm远程终端管理工具最全攻略,涉及下载、安装、字体配置、中文汉化版、中文显示乱码和中文输入乱码、adb tab无效无法补全、Telnet/ssh使用说明、使用技巧等保姆级教程

MobaXterm远程终端管理工具史上最全攻略,涉及下载、安装、字体等配置、解决中文乱码、Telnet/ssh/Serial使用教程、高级功能使用技巧等。MobaXterm 是一个增强型的 Windows 终端。其为 Windows 桌面提供所有重要的远程网络终端工具(如 SSH、X11、RDP、VN…

19、鸿蒙学习——配置HDC命令 环境变量

一、下载Command Line Tools 可参考上篇《鸿蒙学习——配置OHPM、hvigor环境变量》 二、配置hdc环境变量 hdc命令行工具用于HarmonyOS应用/元服务调试所需的工具,该工具存放在命令行工具自带的sdk下的toolchains目录中。为方便使用hdc命令行工具,请将…

Go语言及MongoDB数据库安装配置详解!

Go语言安装 首先讲一下go语言的安装,这部分可直接从官网下载,基本上一键配置的: 官网地址:All releases - The Go Programming Language 选择自己对应系统的安装包,这里官网提供了5种不同的包可自行下载 之后便是默认…

Linux配置ODBC连接Mysql

1、安装mysql 2、安装unixodbc odbcinst -j 查询unixodbc版本以及配置文件路径 3、安装mysql-connector-odbc ####下载 wget https://cdn.mysql.com/archives/mysql-connector-odbc-9.0/mysql-connector-odbc-9.0.0-1.el7.x86_64.rpm ####安装 rpm -ivh mysql-connector-od…

芯片Tapeout power signoff 之IR Drop Redhawk Ploc文件格式及其意义

数字IC后端工程师在芯片流程最后阶段都会使用redhawk或voltus进行设计的IR Drop功耗signoff分析。必须确保静态,动态ir drop都符合signoff标准。 在做redhawk ir drop分析前,我们需要提供一个redhawk ploc供电点坐标。 数字IC设计后端实现前期预防IR D…

数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)

Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣 第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同…

设置首选网络类型以及调用Android框架层的隐藏API

在Android SDK中提供的framework.jar是阉割版本的,比如有些类标记为hide,这些类不会被打包到这个jar中,而有些只是类中的某个方法或或属性被标记为hide,则这些类或属性会被打包到framework.jar,但是我们无法调用&#…

3D几何建模引擎Parasolid功能解析

一、什么是Parasolid? Parasolid是由Siemens PLM Software开发的高精度精密几何建模引擎。它全面评估CAD(计算机辅助设计)、CAM(计算机辅助制造)、CAE(计算机辅助工程)、PLM(产品生…

xinput1_3.dll放在哪里?当xinput1_3.dll丢失时的应对策略:详细解决方法汇总

在计算机系统的运行过程中,我们偶尔会遇到一些令人困扰的问题,其中xinput1_3.dll文件丢失就是较为常见的一种情况。这个看似不起眼的动态链接库文件,实则在许多软件和游戏的正常运行中发挥着至关重要的作用。一旦它丢失,可能会导致…

【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)

本文项目编号 T 098 ,文末自助获取源码 \color{red}{T098,文末自助获取源码} T098,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

CSS(三)盒子模型

目录 Content Padding Border Margin 盒子模型计算方式 使用 box-sizing 属性控制盒子模型的计算 所有的HTML元素都可以看作像下图这样一个矩形盒子: 这个模型包括了四个区域:content(内容区域)、padding(内边距…

LeetCode - Google 校招100题 第7天 序列(数据结构贪心) (15题)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144744418 相关文章: LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (

E-commerce .net+React(一)——项目初始化

文章目录 项目地址一、创建.Net环境1.1环境配置1.1.1 使用vscode创建webapi1.1.2 Clean architecture结构创建1.1.3 将创建好结构的项目添加到git里1.1.4 EF Core配置1. 在infrastructure里安装EF所需环境2. 创建Product数据模型3. 创建EF Core的DbContext 数据库上下文4. 创建…

农家乐系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

NIPS2014 | GAN: 生成对抗网络

Generative Adversarial Nets 摘要-Abstract引言-Introduction相关工作-Related Work对抗网络-Adversarial Nets理论结果-Theoretical Results实验-Experiments优势和不足-Advantages and disadvantages缺点优点 结论及未来工作-Conclusions and future work研究总结未来研究方…

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失如何修复?

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失的修复方法 在畅游《战神:诸神黄昏》这款史诗级游戏的过程中,如果突然遭遇“找不到emp.dll”的错误提示,无疑会打断你的冒险之旅。作为一名深耕软件开…

笔记本通过HDMI转VGA线连接戴尔显示器,wifi不可用或网速变慢

早上开开心心的来使用我的分屏显示器,结果winP开拓展,我的wifi就断掉了,琢磨了好一阵我以为是wifi的问题,发现不进行拓展,网络又好了,一上午就研究这个了,说是hdmi信号干扰了wifi信号啥的额&…

【MATLAB第110期】#保姆级教学 | 基于MATLAB的PAWN全局敏感性分析方法(无目标函数)含特征变量置信区间分析

【MATLAB第110期】#保姆级教学 | 基于MATLAB的PAWN全局敏感性分析方法(无目标函数)含特征变量置信区间分析 一、介绍 PAWN(Probabilistic Analysis With Numerical Uncertainties)是一种基于密度的全局敏感性分析(Gl…