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实现将所有等待资源的线程由等待状态变为就绪状态,接下来如果资源被释放,所有就绪线程将均有机会获得资源并执行。
C#多线程的用法5-线程间的协作Monitor的更多相关文章
- C#多线程的用法8-线程间的协作AutoResetEvent
AutoResetEvent自动重置事件,与ManualResetEvent是相对的而言.它同样用于线程间同步,请对照<C#多线程的用法7-线程间的协作ManualResetEvent>进 ...
- C#多线程的用法3-线程间的协作Join
在创建多线程应用程序时,如何确保线程间的协作往往比让线程工作更重要. 线程间的协作最简单的方式是采用Join来进行,如下: /// <summary> /// 多线程协作-Join方式 / ...
- C#多线程的用法4-线程间的协作lock快捷方式
线程间协作还可通过lock(加锁)方式进行,lock属于C#的Monitor语法糖(Monitor后续讲解).使用简单快捷,如下: /// <summary> /// 多线程协作-lock ...
- C#多线程的用法7-线程间的协作ManualResetEvent
ManualResetEvent:手动重置事件,它用于线程间同步时用法非常简单也易于理解. private static void MultiThreadSynergicWithManualReset ...
- C#多线程的用法6-线程间的协作Mutex
Mutex在线程协作的过程中起互斥的左右,效果与线程锁类似. /// <summary> /// 多线程协作-Mutex /// </summary> private stat ...
- Java并发之线程间的协作
上篇文章我们介绍了synchronized关键字,使用它可以有效的解决我们多线程所带来的一些常见问题.例如:竞态条件,内存可见性等.并且,我们也说明了该关键字主要是一个加锁和释放锁的集成,所有为能获得 ...
- java并发之线程间通信协作
在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- 【转】Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...
随机推荐
- dashDB - Introduction and DB Tools
dashDB - Introduction dashDB is a database that is designed for performance and scale. It offers sea ...
- Vue 实际项目中你可能会遇见的坑
纸上得来终觉浅,绝知此事要躬行! Vue的文档和教程看的太多,小的demo做的多,也不如自己实际的进行一个完整项目的开发.只有做了才知道原来问题这么多,这里列举了一些你做demo教程可能不会遇见的坑. ...
- LCS 算法实现
动态规划算法 #include <iostream> #include <string.h> #include <algorithm> #include <m ...
- 修改WCF的默认序列化格式
需求: 要用WCF生成 Restful风格的接口,返回 JOSN格式: { "AInfo": { ", "Description": ...
- 20170709_python_学习记录
a='ABC';变量赋值时发生了什么 1.在内存中创建一个字符串'ABC' 2.在内存中创建一个变量a指向字符串'ABC' list [] 相当于数组 指向可以变动 str[1,2,3,4] str. ...
- 配置PLSQL,提升工作效率
界面模板的配置: 方便用户快速点击需要的功能.如打开SQL Window 1.打开customize,用户自定义Toolbars对话框. 2.在Commands命令标签页,选中要添加的命令,拖动到工具 ...
- (转)FastJson---高性能JSON开发包
场景:javaBean对象转化为json对象! 1 Fastjson介绍 Fastjson是一个Java语言编写的JSON处理器,由阿里巴巴公司开发.1.遵循http://json.org标准,为其官 ...
- IT软件管理人员的职业路线(从技术经理到总经理) - CEO之公司管理经验谈
技术.业务和管理永远是工作的一个话题.笔者今天就根据自身的经验,通过这三个方面介绍下IT软件管理人员的职业路线.前面写过一个文(IT软件技术人员的职位路线(从程序员到技术总监) - 部门管理经验谈), ...
- 【设计模式】Bridge模式(桥接模式)
最近的一次面试中,被问到桥接模式,以前呢并没有很仔细的研究过这个设计模式,借此机会剖析一下. 先给出自己对这个模式理解后的源码: interface A{ void methodA(); } inte ...
- 程序员面试必备-链表各种操作及其实现方法(c实现)
链表是一种最简单的数据结构之一,经常会被面试官用来考察应聘者的基础扎不扎实,最近也到了求职季,所以我把自己对链表的一些理解写出来,希望能跟大家交流交流: 链表的概念其实挺简单,无非就是一个利用指针将数 ...