c# Monitor.wait() 和sleep的区别
a 、 moniter 继承的积累为object,sleep 继承 thread 类
b、moniter.wait(),会阻塞线程,阻塞的同时但会释放锁,再次获得锁的时候,需要monitor.Pulse唤醒
c、 thread.sleep 是当前的线程休眠,时间到后,自动恢复 继续往下执行
例如:
Monitor.wait() 和Monitor.Pulse用法
1.Monitor.Wait方法
当线程调用 Wait 时,它释放对象的锁并进入对象的等待队列,对象的就绪队列中的下一个线程(如果有)获取锁并拥有对对象的独占使用。Wait()就是交出锁的使用权,使线程处于阻塞状态,直到再次获得锁的使用权。
2.Monitor.Pulse方法
当前线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。pulse()并不会使当前线程释放锁。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Wait和Sleep
{
class Program
{
static object locker = new object();
static Thread thread1 = new Thread(TestTwo);
static void Main(string[] args)
{
Thread thread = new Thread(TestWait);
thread.Start();
lock (locker)
{
Console.WriteLine($"线程拥有锁");
Console.WriteLine($"线程开始休眠");
for (int i = 0; i < 3; i++)
{
Thread.Sleep(1000);
Console.WriteLine($"Main{i}");
}
Console.WriteLine($"线程休眠结束");
}
Console.ReadLine();
}
static void TestWait()
{
Console.WriteLine($"TestWait");
//这里会等待locker 释放
lock (locker)
{
Console.WriteLine($"开始wait");
thread1.Start();
Console.WriteLine($"开始wait并且释放锁,阻塞当前线程向下执行,直到再一次获取锁");
var satus = Monitor.Wait(locker, 2000); //释放对象上的锁并阻止当前线程,直到它重新获取该锁。如果已用指定的超时时间间隔,则线程进入就绪队列。
if (!satus)
{
Console.WriteLine("超时");
}
while (satus)
{
Console.WriteLine($"TestWait已获取锁,继续执行");
Console.WriteLine("TestWait通知释放锁");
Monitor.Pulse(locker);//
Console.WriteLine("TestWait通知完成");
break;
}
}
}
static void TestTwo()
{
lock (locker)
{
Console.WriteLine("TestTwo获取锁");
for (int i = 0; i < 3; i++)
{
Thread.Sleep(1000);
Console.WriteLine($"TestTwo{i}");
}
Console.WriteLine("通知下一个线程获取该锁");
Monitor.Pulse(locker);
}
}
}
}
var satus = Monitor.Wait(locker, 2000); //释放对象上的锁并阻止当前线程,直到它重新获取该锁。如果已用指定的超时时间间隔,则线程进入就绪队列。
wait方法会释放locker,同时阻塞线程(阻止往下执行),同时,testTwo中就可以获得该锁,testtwo执行完毕之后调用moniter.pulse方法,通知其它线程,locker锁使用完毕,这时testwait中的monitor.wait再次获得锁,如果在2000毫秒还没等到其它线程释放锁,则自动往下执行
版权归原作者 zls365365 所有, 如有侵权,请联系我们删除。