【开发笔记系列(一)】C#多线程 线程等待
在开发中遇到问题、技术点、解决方法、技术拓展、原理深究,把这些解决过程作为随笔记录下来。所以就有笔记系列,持续更新……
认真探究多线程前,只会new Thread;锁?Lock;线程等待?Thread.Sleep()。
例如 Thread.Sleep()、Thread.SpinWait();、{某种锁}.WaitOne() 等。
这些等待会影响代码的算法逻辑和程序的性能,也有可能会造成死锁,在本篇探究线程中等待。
三种常用等待
这三种等待分别是:
- Thread.Sleep();
- Thread.SpinWait();
- Task.Delay();
函数 | 注解 |
---|---|
Thread.Sleep(); | 会阻塞线程,使得线程交出时间片,然后处于休眠状态,直至被重新唤醒; 适合用于长时间的等待; |
Thread.SpinWait(); | 使用了自旋等待,等待过程中会进行一些的运算,线程不会休眠,用于微小的时间等待; 长时间等待会影响性能; |
Task.Delay(); | 用于异步中的等待。 |
这里我们还需要继续 SpinWait 和 SpinLock 这两个类型,最后再进行总结对照。
SpinLock 结构
属性和方法
SpinLock 常用属性和方法如下:
属性:
属性 | 说明 |
---|---|
IsHeld | 获取锁当前是否已由任何线程占用。 |
IsHeldByCurrentThread | 获取锁是否已由当前线程占用。 |
IsThreadOwnerTrackingEnabled | 获取是否已为此实例启用了线程所有权跟踪。 |
方法:
方法 | 说明 |
---|---|
Enter(Boolean) | 采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下, 都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。 |
Exit() | 释放锁。 |
Exit(Boolean) | 释放锁。 |
TryEnter(Boolean) | 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下, 都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。 |
TryEnter(Int32, Boolean) | 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下, 都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。 |
TryEnter(TimeSpan, Boolean) | 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下, 都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。 |
示例
SpinLock 的模板如下:
private static void DoWork()
{
SpinLock spinLock = new SpinLock();
bool isGetLock = false; // 是否已获得了锁
try
{
spinLock.Enter(ref isGetLock);// 运算
}
finally
{
if (isGetLock)
spinLock.Exit();
}
}
Thread.Sleep() 会发生上下文切换,出现比较大的性能损失。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗