• [.net 多线程]Monitor


    Monitor 类通过向单个线程授予对象锁来控制对对象的访问。对象锁提供限制访问代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该锁。还可以使用 Monitor 来确保不会允许其他任何线程访问正在由锁的所有者执行的应用程序代码节,除非另一个线程正在使用其他的锁定对象执行该代码。

    Monitor通过enter和exit函数的组合,可以等效lock效果

    1 Monitor.Enter(obj);
    2 //...
    3 Monitor.Exit(obj);
    4 
    5 lock(obj)
    6 {
    7      //...     
    8 }
    对象锁等效

    与lock不同在于,Monitor更加灵活,可以通过Wait/Pulse,形成线程间的同步管理。当前获取到锁的线程(TA)通过Wait函数,释放对锁的控制,并将当前线程挂起为阻塞状态。这个时候其他线程就可以对锁资源进行竞争(假设在众多线程中TB获取到锁)。TA只有在接收到TB的Pulse信号,才能重新进入就绪状态,重新竞争锁资源。

    注意Pulse函数是通知当前等待队列中第一个,PulseAll是通知所有等待队列中的线程。

     1 Thread th2 = new Thread(() =>
     2 {
     3     lock (aysncLock)
     4     {
     5         Console.WriteLine("th2 enter will wait");
     6         Monitor.Wait(aysncLock);
     7         Console.WriteLine("th2 continue");
     8     }
     9 });
    10 Thread th3 = new Thread(() =>
    11 {
    12     lock (aysncLock)
    13     {
    14         Console.WriteLine("th3 enter will wait");
    15         Monitor.Wait(aysncLock);
    16         Console.WriteLine("th3 continue");
    17     }
    18 });
    19 Thread th1 = new Thread(() => 
    20 {
    21     Thread.Sleep(TimeSpan.FromSeconds(1));
    22     lock (aysncLock)
    23     {
    24         Console.WriteLine("th1 enter will pulseall");
    25         Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
    26         Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
    27         //Monitor.PulseAll(aysncLock);
    28         Monitor.Pulse(aysncLock);
    29         Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
    30         Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
    31         Console.WriteLine("th1 exit");
    32     }
    33     Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
    34     Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
    35 });
    36 
    37 th1.Start();
    38 th2.Start();
    39 th3.Start();
    40 Console.ReadKey();

    使用Pulse结果:

    th2、th3只有一个执行

    使用PulseAll结果:

    th2、th3均执行

  • 相关阅读:
    深入JAVA注解之属性注解
    深入JAVA注解之方法注解
    C# 启动外部程序的几种方法
    在.NET中实现彩色光标/动画光标和自定义光标[转]
    C#实现汉诺塔问题
    ExecuteNonQuery()返回值注意点
    在VS2012下不安装VS2010编译VS2010的工程
    Windows 窗体的.Net 框架绘图技术
    使用DataSet Datatable 更新数据库的三种方式
    C#.net 之货币转换
  • 原文地址:https://www.cnblogs.com/deepminer/p/8995005.html
Copyright © 2020-2023  润新知