C# 多线程详解 Part.04(Lock、Monitor、生产与消费)

///
/// 被操作的对象
///
public class Cell
{
///
/// Cell 对象里的内容
///
int cellContents;

///
/// 状态标志: 为 true 时可以读取,为 false 则正在写入
///
bool readerFlag = false;

public int ReadFromCell()
{
lock (this)
{
if (!readerFlag)
{
try
{
// 等待 WriteToCell 方法中调用 Monitor.Pulse()方法
Monitor.Wait(this);
}
catch (SynchronizationLockException e)
{
Console.WriteLine(e);
}
catch (ThreadInterruptedException e)
{
Console.WriteLine(e);
}
}

// 开始消费行为
Console.WriteLine("Consume: {0}", cellContents);
Console.WriteLine();

// 重置 readerFlag 标志,表示消费行为已经完成
readerFlag = false;

// 通知 WriteToCell()方法(该方法在另外一个线程中执行,等待中)
Monitor.Pulse(this);
}
return cellContents;
}

public void WriteToCell(int n)
{
lock (this)
{
if (readerFlag)
{
try
{
Monitor.Wait(this);
}
catch (SynchronizationLockException e)
{
// 当同步方法(指Monitor类除Enter之外的方法)在非同步的代码区被调用
Console.WriteLine(e);
}
catch (ThreadInterruptedException e)
{
// 当线程在等待状态的时候中止
Console.WriteLine(e);
}
}
cellContents = n;
Console.WriteLine("Produce: {0}", cellContents);
readerFlag = true;
Monitor.Pulse(this); // 通知另外一个线程中正在等待的 ReadFromCell() 方法
}
}
}

///
/// 生产者
///
public class CellProd
{
///
/// 被操作的 Cell 对象
///
Cell cell;

///
/// 生产者生产次数,初始化为 1
///
int quantity = 1;

public CellProd(Cell box, int request)
{
cell = box;
quantity = request;
}

public void ThreadRun()
{
for (int looper = 1; looper         {            // 生产者向操作对象写入信息             cell.WriteToCell(looper);        }    }} /// /// 消费者/// public class CellCons{    Cell cell;    int quantity = 1;     public CellCons(Cell box, int request)    {        cell = box;        quantity = request;    }     public void ThreadRun()    {        int valReturned;        for (int looper = 1; looper         {            valReturned = cell.ReadFromCell(); // 消费者从操作对象中读取信息         }    }} /// /// 测试类/// public class MonitorSample{    public static void Main(String[] args)    {        // 一个标志位,如果是 0 表示程序没有出错,如果是 1 表明有错误发生        int result = 0;         // 下面使用 cell 初始化 CellProd 和 CellCons 两个类,生产和消费次数均为 20 次         Cell cell = new Cell();        CellProd prod = new CellProd(cell, 20);        CellCons cons = new CellCons(cell, 20);        Thread producer = new Thread(new ThreadStart(prod.ThreadRun));        Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));         // 生产者线程和消费者线程都已经被创建,但是没有开始执行         try        {            producer.Start();            consumer.Start();            producer.Join();            consumer.Join();            Console.ReadLine();        }        catch (ThreadStateException e)        {            // 当线程因为所处状态的原因而不能执行被请求的操作             Console.WriteLine(e);            result = 1;        }        catch (ThreadInterruptedException e)        {            // 当线程在等待状态的时候中止             Console.WriteLine(e);            result = 1;        }        // 尽管 Main() 函数没有返回值,但下面这条语句可以向父进程返回执行结果         Environment.ExitCode = result;    }}

Original: https://www.cnblogs.com/SkySoot/p/3494609.html
Author: SkySoot
Title: C# 多线程详解 Part.04(Lock、Monitor、生产与消费)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/539888/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JDK成长记15:从0分析你不知道的synchronized底层原理(上)

    前几节你应该已经了解和掌握了Thread、ThreadLocal、Volatile这几个并发基础知识的底层原理。这一节,你可以跟我一起深入了解下synchronized关键字的底层…

    Java 2023年6月5日
    092
  • 《认知觉醒》读书笔记

    《认知觉醒》这本书分为两个部分,第一部分是 内观自己,摆脱焦虑,第二部分是 外观世界,借力前行。前者从大脑、潜意识、元认知三个方面帮助我们认识自己,审视自己内心焦虑不安的原因。后者…

    Java 2023年6月5日
    0110
  • 『硬核』Spring完整版学习笔记,动力节点王鹤

    Spring学习笔记(来自王鹤老师讲的最新版Spring) spring笔记官方下载地址:动力节点官网 视频观看地址 https://www.bilibili.com/video/…

    Java 2023年6月9日
    042
  • Centos7: 防火墙相关

    防火墙 开放端口 firewall-cmd –zone=public –add-port=5672/tcp –permanent # 开&#x6…

    Java 2023年6月7日
    078
  • 聊聊客户档案模型的设计与管理

    可以简单,更需要复杂; 一、基础描述 围绕客户管理通常分为售前、售中、售后、三个核心阶段,即营销、销售、服务三个核心流程与策略,在之前的文章中有聊过CDP系统的设计,本篇从客户档案…

    Java 2023年6月15日
    075
  • 线程池,我是谁?我在哪儿?

    大家好,这篇文章跟大家探讨下日常使用线程池的各种姿势,重点介绍怎么在 Spring 环境中正确使用线程池。 线程池使用姿势 首先问大家一个问题,你日常开发中是怎样使用线程池的? 我…

    Java 2023年6月14日
    081
  • 七、注释、标识符、数据类型与类型转换

    书写注释是一个好习惯 public class Comment { public static void main(String[] args) { //单&…

    Java 2023年6月5日
    071
  • html css中有哪些属性可以继承,哪些不可以继承

    css样式表继承指的是,特定的css属性向下传递到后代元素 为了看到继承的实际应用,我们将使用下面的HTML代码。 <p> <em> 继承em> p&…

    Java 2023年6月13日
    066
  • 数据库学习记录(二)

    1.count(*)和count(具体的某个字段),他们有什么区别? count(*):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关) count(comm)…

    Java 2023年6月7日
    054
  • 全链路spring cloud sleuth+zipkin

    一、About ZipKin please google 二、 Demo Scene 三、 Result Display 四、Prepare 1、soft version kafk…

    Java 2023年5月30日
    0100
  • [Java] HashMap 源码简要分析

    允许null作为key/value。 不保证按照插入的顺序输出。使用hash构造的映射一般来讲是无序的。 非线程安全。 内部原理与Hashtable类似。 源码简要分析 java;…

    Java 2023年5月29日
    062
  • 删除链表中的节点_237_83_82_203

    请编写一个函数,用于删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问要被删除的节点 。 题目数据保证需要删除的节点不是末尾节点 。…

    Java 2023年6月5日
    072
  • 2.servlet实现用户登录功能

    在该案例中,通过servlet实现了用户登录的功能。主要涉及前端页面请求数据,servlet程序处理请求,业务逻辑层调用相关的dao层,在数据库提取数据并return给servic…

    Java 2023年6月8日
    079
  • 接下来或许是一年中跳槽的最佳时间

    一般来说,很多人都认为一年中最佳的跳槽时间是三、四月份,也就是我们常说的”金三银四”。 但我认为”金三银四”不一定是性价比最佳的时间…

    Java 2023年6月7日
    082
  • Python 知识点总结

    本知识点总结由@Chi-Tang编写 是 Python 最常用的一种数据结构,用一组方括号括起来、用逗号分隔开的一组数据。 列表的元素可以是任意类型,但使用时通常各个元素的类型是相…

    Java 2023年6月7日
    049
  • cassandra 数据到Java对象的映射绑定

    类似Hibernate和MyBatis的关系映射,自动帮你将查询数据或是修改的参数进行数据映射和绑定。支持查询后返回数据ResultSet到Java对象的映射,支持修改、删除、查询…

    Java 2023年5月29日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球