之前我们使用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. CSS3学习系列之布局样式(二)

    使用盒布局 在CSS3中,通过box属性来使用盒布局,例子如下: <!DOCTYPE html> <html lang="en"> <head> ...

  2. 什么是Hadoop

    配上官方介绍 What Is Apache Hadoop?    The Apache™ Hadoop® project develops open-source software for relia ...

  3. tp框架---View视图层---模板继承(举例说明)

    当我们做动态页面时,我们会发现一个网站的头部和尾部是相同的,那么我们如何用tp框架来做模板呢 ? 先看一下注意事项: (1)每个区块由<block></block>标签组成 ( ...

  4. HashMap源码深入研究

    简介 HashMap是采用链表和位桶来来实现的,由于一个位桶存在元素太多会导致get效率低,因此在jdk1.8中采用的红黑树实现,当链表长度大于TREEIFY_THRESHOLD(值为8)时会转换为红 ...

  5. PHP面向对象 ——多态

    接口 接口(interface)是抽象方法和静态常量定义的集合. 接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量. 接口中没有其它类型的内容 接口的定义 /** * 接口可以认为是特殊的 ...

  6. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  7. 阿里云服务器Windows Server 2008/2012部署Office Web Server 2013

    以前成功将Office Web Server 2013部署在了本地服务器上,此次是将Office Web Server 2013部署在阿里云服务器Windows Server 2008和2012上,中 ...

  8. [COGS 2051] 王者之剑

    Saber大法吼 2051. 王者之剑 ★★★☆   输入文件:Excalibur.in   输出文件:Excalibur.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述 ...

  9. 解决删除元素动画的bug

    效果说明 首先说明一下我需要做到的效果 其实很简单---点击删除按钮的时候,加入删除动画 删除动画是这样的,高度和宽度都会均匀的变小,内部的元素需要被隐藏(因为会有文字挤在一起):直到变为0结束,时长 ...

  10. IMPEX

    1.Impex是基于java Model的一种面向对象的数据操作手段,因此写impex代码前需要理清java Model之间的依赖关系. 2.基本语法:mode type[modifier=value ...