• C#多线程的用法5-线程间的协作Monitor


    之前我们使用lock快捷方式,实现了多线程对同一资源的共享。在C#中lock实际上是Monitor操作的简化版本。

    下面使用Monitor来完成之前的lock功能,你可以在此做一下对照:

    private static void MultiThreadSynergicWithMonitor()
            {
                int[] array = new int[3];
    
                Thread producer = new Thread(() =>
                {
                    int count = 0;
                    Random random = new Random();
                    while (true)
                    {
                        if (10 == count)
                            break;
    
                        Monitor.Enter(array);
                        array[0] = random.Next(10);
                        array[1] = random.Next(10);
                        array[2] = random.Next(10);
                        count++;
                        Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
                        Monitor.Exit(array);
                    }
                })
                {
                    Name = "producer"
                };
                Thread customer = new Thread(() =>
                {
                    int count = 0;
                    while (true)
                    {
                        if (10 == count)
                            break;
    
                        Monitor.Enter(array);
                        count++;
                        Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
                        array[0] = 0;
                        array[1] = 0;
                        array[2] = 0;
    Monitor.Exit(array);
                    }
                    
                })
                {
                    Name = "customer"
                };
    
                producer.Start();
                customer.Start();
            }
    

    通过对比聪明的你可定发现,lock(xx){ }等效于 Monitor.Enter(x'x)与Monitor.Exit(xx)的组合,实际上lock就是Monitor的语法糖。

    因此Monitor比lock在控制线程协作方面更为 强大,如下:

    /// <summary>
            /// 多线程协作-Monitor方式
            /// 成功解决多线程对单一资源的共享
            /// 并解决多个线程间同步问题
            /// </summary>
            private static void MultiThreadSynergicWithMonitor()
            {
                int[] array = new int[3];
    
                Thread producer = new Thread(() =>
                {
                    int count = 0;
                    Random random = new Random();
                    while (true)
                    {
                        if (10 == count)
                            break;
    
                        Monitor.Enter(array);
                        array[0] = random.Next(10);
                        array[1] = random.Next(10);
                        array[2] = random.Next(10);
                        count++;
                        Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
                        Monitor.Pulse(array);
                        Monitor.Wait(array);
                    }
                    Monitor.Exit(array);
                })
                {
                    Name = "producer"
                };
                Thread customer = new Thread(() =>
                {
                    int count = 0;
                    while (true)
                    {
                        if (10 == count)
                            break;
    
                        Monitor.Enter(array);
                        count++;
                        Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
                        array[0] = 0;
                        array[1] = 0;
                        array[2] = 0;
                        Monitor.Pulse(array);
                        Monitor.Wait(array);
                    }
                    Monitor.Exit(array);
                })
                {
                    Name = "customer"
                };
    
                producer.Start();
                customer.Start();
            }
    

      上面的代码与之前的lock代码功能类似但却不相同,它实现了producer线程与customer线程的交替运行(与lock方式相比控制更加精细),再次建议你执行一下实际代码,你会很容易发现两者却别。

    说明:

    1、Monitor.Pulse(xx)实现通知等待xx资源的某一个线程由等待状态(等待队列)变更为就绪状态(就绪队列),从而做好准备在调用Monitor.Pulse(x'x)功能的线程释放资源时马上锁定释放的资源。

    2、Monitor.Wait(xx)实现调用该方法的线程暂时释放锁定的资源,并让该线程进入等待线程队列。所以线程在调用该方法后会临时中断后续代码的执行,在该线程再次获得资源时,

    将回到中断继续执行。

    3、Monitor.PulseAll(xx)是Monitor.Pulse(xx)扩大版,如果你理解了Monitor.Pulse(xx)并且知道线程状态的变更(线程所属队列的变化),那么理解Monitor.PulseAll就简单多了

    Monitor.PulseAll实现将所有等待资源的线程由等待状态变为就绪状态,接下来如果资源被释放,所有就绪线程将均有机会获得资源并执行。

  • 相关阅读:
    PTA数据结构与算法题目集(中文) 7-6
    PTA数据结构与算法题目集(中文) 7-5
    PTA数据结构与算法题目集(中文) 7-4
    PTA数据结构与算法题目集(中文) 7-3
    数据结构学习第二十三天
    数据结构学习第二十三天
    数据结构学习第二十二天
    数据结构学习第二十一天
    数据结构学习第二十天
    并发之ATOMIC原子操作--CAS乐观锁原理(二)
  • 原文地址:https://www.cnblogs.com/dw039/p/7400916.html
Copyright © 2020-2023  润新知