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

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

  1. C#多线程的用法8-线程间的协作AutoResetEvent

    AutoResetEvent自动重置事件,与ManualResetEvent是相对的而言.它同样用于线程间同步,请对照<C#多线程的用法7-线程间的协作ManualResetEvent>进 ...

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

    在创建多线程应用程序时,如何确保线程间的协作往往比让线程工作更重要. 线程间的协作最简单的方式是采用Join来进行,如下: /// <summary> /// 多线程协作-Join方式 / ...

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

    线程间协作还可通过lock(加锁)方式进行,lock属于C#的Monitor语法糖(Monitor后续讲解).使用简单快捷,如下: /// <summary> /// 多线程协作-lock ...

  4. C#多线程的用法7-线程间的协作ManualResetEvent

    ManualResetEvent:手动重置事件,它用于线程间同步时用法非常简单也易于理解. private static void MultiThreadSynergicWithManualReset ...

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

    Mutex在线程协作的过程中起互斥的左右,效果与线程锁类似. /// <summary> /// 多线程协作-Mutex /// </summary> private stat ...

  6. Java并发之线程间的协作

    上篇文章我们介绍了synchronized关键字,使用它可以有效的解决我们多线程所带来的一些常见问题.例如:竞态条件,内存可见性等.并且,我们也说明了该关键字主要是一个加锁和释放锁的集成,所有为能获得 ...

  7. java并发之线程间通信协作

    在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...

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

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  9. 【转】Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...

随机推荐

  1. YARN框架详解

    YARN框架详解 YARN官方解释 YARN是什么 The fundamental(定义) idea of YARN is to split(分开) up the functionalities(功能 ...

  2. Java数据类型在实际开发中的应用一

    在前边的博文中,我已经介绍了Java核心的容器IO等,现在我来说一下java中的数据类型.在java中,一切东西皆为对象(这句话意思是java中绝大数情况都用对象),极少数不是对象的,也存在与之对应的 ...

  3. My sql添加远程用户root密码为password

    添加远程用户root密码为password grant all privileges on *.* to root@localhost identified by '123321' with gran ...

  4. JavaScript实现一个复数类

    <script type="text/javascript"> /** * 这里定义Complex类,用来描述复数 */ /** * 这个构造函数为它所创建的每个实例定 ...

  5. Java语言的9个主要特性

    Java作为时下很流行的一门编程语言,受到很多人的热爱,那么它有哪些特性呢?一起来看看吧. 1.Java语言是简单的 Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用.另 ...

  6. python selenium自动化之-环境搭建

    安装python和pip上述文章有介绍,在这里不在赘述.直接安装seleinum pip3 install selenium 安装完成以后, pip3 show selenium 显示 Name: s ...

  7. 不同浏览器创建 ajax XMLHTTPRequest对象的方法及兼容性问题总结

    XMLHttpRequest 对象是AJAX功能的核心,要开发AJAX程序必须从了解XMLHttpRequest 对象开始. 了解XMLHttpRequest 对象就先从创建XMLHttpReques ...

  8. 英语曰曰曰No.523

    ---恢复内容开始--- [一句话新闻] The iPhone's 10th Anniversary:Can Apple Revive Its iPhone Sales ? 1.A look back ...

  9. Missing number - 寻找缺失的那个数字

    需求:给出一个int型数组,包含不重复的数字0, 1, 2, ..., n:找出缺失的数字: 如果输入是[0, 1, 2] 返回 3 输入数组 nums = [0, 1, 2, 4] :应该返回 3 ...

  10. 华为OJ之放砝码

    题目描述: 现有一组砝码,重量互不相等,分别为m1.m2--mn:他们可取的最大数量分别为x1.x2--xn.现在要用这些砝码去称物体的重量,问能称出多少中不同的重量. 注: 称重重量包括0: 要对输 ...