C# 中的Monitor和thread.join

本文深入探讨了C#中Monitor类的使用方法及其与lock关键字的关系,解析了线程状态转换机制,包括runing、wait和ready状态,并通过代码示例展示了Monitor.Wait()和Monitor.Pulse()如何实现线程间的资源传递,避免死锁。

Lock内部调用的就是Monitor
其实lock在IL代码中会被翻译成Monitor。
也就是Monitor.Enter(obj)和Monitor.Exit(obj).
lock(obj)
{
}
等价为:
try
{

Monitor.Enter(obj)
}
catch()
{}
finally
{

onitor.Exit(obj)  

}
主要说Monitor的两个方法,wait()和pause()
在lock代码里面如果调用了Monitor.Wait(),会放弃对资源的所有权,让别的线程lock进来。然后别的线程代码里Pulse一下(让原线程进入到等待队列),然后在Wait一下释放资源,这样原线程的就可以继续执行了(代码还堵塞在wait那句话呢)。
也就是说,必须两个或多个线程共同调用Wait和Pulse,把资源的所有权抛来抛去,才不会死锁。

线程主要有三种状态
①runing
②wait
③ready

  1. pulse(obj)用于将线程从wait状态跟改为ready状态,当此线程执行完成时,或者此线程状态更改为wait时,将从ready状态中选择执行
  2. wait(obj),将线程从runing状态更改为wati状态,若要继续执行,需要先更改为ready状态
代码示例:
static void Main(string[] args)
        {
            object obj = new object();
            Task.Run(() => {
                lock (obj)
                {
                    Console.WriteLine("lockA");
                    Thread.Sleep(1000);
                    //此线程状态更改为wait,进入阻塞状态
                    Monitor.Wait(obj);
                    Monitor.Pulse(obj);
                }
                Console.WriteLine("Aover");
            });
            Task.Run(() => {
                lock (obj)
                {
                    Console.WriteLine("lockB");
                    Thread.Sleep(500);
                    Monitor.Pulse(obj);
                    Monitor.Wait(obj);
                }
                Console.WriteLine("Bover");
            });

结果:
lockA
lockB
Aover
Bover
两个线程间踢皮球
A->B->A-B

Thread.Join()

Thread.Join()相当于task.wait(); 阻塞当前线程,等待任务完成。

和AutoEvent相似是处理同步关系的,但是AutoEvent是跨进程的,而Monitor是针对线程的。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值