zoukankan      html  css  js  c++  java
  • C#多线程编程之:Monitor使用示例及Mutex简介

    C#多线程编程之:Monitor使用示例及Mutex简介

    Monitor类功效和lock类似:

    System.Object obj = (System.Object)x;
    System.Threading.Monitor.Enter(obj);
    try {
       DoSomething();
    }finally{
       System.Threading.Monitor.Exit(obj);
    }

      lock关键字比Monitor简洁,其实lock就是对Monitor的Enter和Exit的一个封装。

      另外,Monitor还有几个常用的方法:

      (1) TryEnter

      TryEnter能够有效的决绝长期死等的问题,如果在一个并发经常发生,而且持续时间长的环境中使用TryEnter,可以有效防止死锁或者长时间的等待。

      比如我们可以设置一个等待时间:

      bool gotLock = Monitor.TryEnter(myobject,1000)

      让当前线程在等待1000秒后根据返回的bool值来决定是否继续下面的操作。

      (2) Pulse、PulseAll、Wait

      Pulse以及PulseAll还有Wait方法是成对使用的,它们能让你更精确的控制线程之间的并发。

      示例代码:

    
     

    1 using System.Threading;
    2
    3 public class Program
    4 {
    5 //同步对象
    6 static object ball = new object();
    7
    8 public static void Main()
    9 {
    10 //创建并启动线程
    11 Thread threadPing = new Thread(ThreadPingProc);
    12 Thread threadPong = new Thread(ThreadPongProc);
    13
    14 threadPing.Start();
    15 threadPong.Start();
    16
    17 System.Console.ReadLine();
    18 }
    19
    20 static void ThreadPingProc()
    21 {
    22 System.Console.WriteLine("Thread Ping Start!");
    23
    24 //锁定ball
    25 lock (ball)
    26 {
    27 for (int i = 0; i < 5; i++)
    28 {
    29 System.Console.WriteLine("ThreadPing: Ping ");
    30 //通知队列中锁定对象ball的状态更改
    31 Monitor.Pulse(ball);
    32 //释放ball对象上的锁,并阻止该线程,直到它重新获得ball对象锁
    33 Monitor.Wait(ball);
    34 }
    35
    36 //通知队列中锁定对象ball的状态更改
    37 Monitor.Pulse(ball);
    38 }
    39
    40 System.Console.WriteLine("ThreadPing: Bye!");
    41 }
    42
    43 static void ThreadPongProc()
    44 {
    45 System.Console.WriteLine("Thread Pong Start!");
    46
    47 //锁定ball
    48 lock (ball)
    49 {
    50 for (int i = 0; i < 5; i++)
    51 {
    52 System.Console.WriteLine("ThreadPong: Pong ");
    53 //通知队列中锁定对象ball的状态更改
    54 Monitor.Pulse(ball);
    55 //释放ball对象上的锁,并阻止该线程,直到它重新获得ball对象锁
    56 Monitor.Wait(ball);
    57 }
    58
    59 //通知队列中锁定对象ball的状态更改
    60 Monitor.Pulse(ball);
    61 }
    62
    63 System.Console.WriteLine("ThreadPong: Bye!");
    64 }
    65 }

      执行结果如下:

      ThreadPing: Hello!

      ThreadPing: Ping 
      ThreadPong: Hello! 
      ThreadPong: Pong 
      ThreadPing: Ping 
      ThreadPong: Pong 
      ThreadPing: Ping 
      ThreadPong: Pong 
      ThreadPing: Ping 
      ThreadPong: Pong 
      ThreadPing: Ping 
      ThreadPong: Pong 
      ThreadPing: Bye!

      ThreadPong: Bye!
      当threadPing进程进入ThreadPingProc锁定ball并调用Monitor.Pulse(ball )后,它通知threadPong从阻塞队列进入准备队列。当threadPing调用Monitor.Wait(ball)阻塞自己后,它放弃了了对ball的锁定,所以threadPong得以执行。PulseAll与Pulse方法类似,不过它是向所有在阻塞队列中的进程发送通知信号,如果只有一个线程被阻塞,那么请使用Pulse方法。

    Mutex 对象 
    Mutex与Monitor类似,这里不再累赘。需要注意的是Mutex分两种:一种是本地Mutex,一种是系统级Mutex。系统级Mutex可以用来进行跨进程间的线程的同步。
    尽管 Mutex 可以用于进程内的线程同步,但是使用 Monitor 通常更为可取,因为Monitor是专门为 .NET Framework 而设计的,因而它可以更好地利用资源。
    相比之下,Mutex 类是 Win32 构造的包装。尽管 Mutex 比Monitor更为强大,但是相对于 Monitor 类,它所需要的互操作转换更消耗计算资源。

    

  • 相关阅读:
    shell文件包含
    shell输入/输出重定向
    shell流程控制
    shell echo命令(六)
    shell基本运算符(五)
    shell数组(四)
    shell传递参数-$的用法(三)
    SQL 注入 处理
    WPF 还未开始我就打算结束
    Java SDK 2.0
  • 原文地址:https://www.cnblogs.com/grj001/p/12223687.html
Copyright © 2011-2022 走看看