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实现将所有等待资源的线程由等待状态变为就绪状态,接下来如果资源被释放,所有就绪线程将均有机会获得资源并执行。

时间: 2024-12-28 15:49:18

C#多线程的用法5-线程间的协作Monitor的相关文章

C#多线程的用法3-线程间的协作Join

在创建多线程应用程序时,如何确保线程间的协作往往比让线程工作更重要. 线程间的协作最简单的方式是采用Join来进行,如下: /// <summary> /// 多线程协作-Join方式 /// 解决线程间同步工作问题 /// </summary> private static void MultiThreadSynergicWithJoin() { int[] array = new int[3]; Thread producer = null, customer = null;

C#多线程的用法4-线程间的协作lock快捷方式

线程间协作还可通过lock(加锁)方式进行,lock属于C#的Monitor语法糖(Monitor后续讲解).使用简单快捷,如下: /// <summary> /// 多线程协作-lock快捷方式 /// 成功解决多线程对单一资源的共享 /// </summary> private static void MultiThreadSynergicWithLock() { int[] array = new int[3]; Thread producer = new Thread(()

C#多线程的用法6-线程间的协作Mutex

Mutex在线程协作的过程中起互斥的左右,效果与线程锁类似. /// <summary> /// 多线程协作-Mutex /// </summary> private static void MultiThreadSynergicWithMutex() { Mutex mutex = new Mutex(true); Thread thread1 = new Thread(() => { mutex.WaitOne(); for (var i = 0; i < 5; i

iOS多线程开发小demo5 线程间的通信

// DYFViewController.m // 623-06-线程间的通信 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @property (weak, nonatomic) IBOutlet UIImag

Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

Java并发编程系列[未完]: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程:线程间的协作(wait/notify/sleep/yield/join) 一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线程创建完成时为新

黑马程序员——JAVA基础之Day24 多线程 ,死锁,线程间通信 ,线程组,线程池,定时器。

------- android培训.java培训.期待与您交流! ---------- Lock()实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作. private Lock lock =new ReentrantLock(); 被锁的代码要用   lock.lock()                lock.unlock()    包括.其中用try   ...finally包围 同步:效率低,如果出现同步嵌套,会出现死锁.  但是安全. 死锁问题:两个或者两个以上

Java多线程之死锁与线程间通信简单案例

死锁定义 死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源:我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁:具体其死锁代码如下:

java多线程详解(6)-线程间的通信wait及notify方法

Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New):线程对象已经产生,但尚未被启动,所以无法执行.如通过new产生了一个线程对象后没对它调用start()函数之前.(2). 可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它. 当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它

多线程编程-- part 4 线程间的通信

线程间的相互作用 线程之间需要一些协调通信,来共同完成一件任务. Object类相关的方法:notify(),notifyAll(),wait().会被所有的类继承,这些方法是final不能被重写.他们操控的是每个对象都会有的锁,如果不在synchronized里面调用wait,notify,notifyAll方法,运行时会报异常:要调用对象的这些方法,必须先获得这个对象的锁. wait(): 使得当前线程必须等待,进入到等待序列,等到另外一个线程调用notify()或者notifyAll()激