c#中的多线程同步

在处理多线程同步问题的时候,我们一般有临界区,互斥量,信号量和消息机制等几种解决方案,在c#中可以非常方便的使用它们来实现进程的同步。下面我就常用的lock,Monitor和Mutex几种来说明如何实现进程的同步。

    lock和Monitor依靠一种“令牌”对象来实现进程的同步,下面看一段示范代码:

 

   class Example
    {
        int count = 0;
        object o = new object();//令牌对象
        static void Main(string[] args)
        {
            Example e=new Example();
            Thread pthread = new Thread(e.produce);
            Thread cthread = new Thread(e.consume);

            pthread.Start();

            cthread.Start();

        }
        public void produce()
        {
            while (true)
            {
                lock (o)
                {
                    count = count + 1;
                }
            }
        }
        public void consume()
        {
            while (true)
            {
                lock (o)
                {
                    count = count - 1;
                }
            }
        }
    }

        在程序中,我们需要产生两个生产和消费的线程,但是两个线程对count的访问必须是互斥的,也就是要实现两个现场的同步。在上面的代码中,首先实例化一个令牌对象o,当需要操作互斥变量count的时候,我就用lock关键字去取令牌,如果此时令牌可以拿到,就执行对count的操作,然后释放令牌。如果此时令牌在另外一个线程手里,就等待知道该令牌被释放。Monitor的使用与lock很相似,下面附上使用代码,不再另加说明:

      Monitor.Enter(o);

      count=count+1;

      Monitor.Exit(o);

        Mutex是使用互斥的机制来实现进程的同步,Mutex不需要使用额外的令牌对象。下面是用Mutex来解决著名的生产者消费者问题,设定消费者和生产者各3个,公共区容量为5,生产100个,下面看代码:

         class Program
    {
        static void Main(string[] args)
        {
            ProduceAndConsume pac=new ProduceAndConsume();
            Thread pthread1 = new Thread(pac.produce);
            Thread pthread2 = new Thread(pac.produce);
            Thread pthread3 = new Thread(pac.produce);
            Thread cthread1 = new Thread(pac.consume);
            Thread cthread2 = new Thread(pac.consume);
            Thread cthread3 = new Thread(pac.consume);
            pthread1.Start();
            pthread2.Start();
            pthread3.Start();
            cthread1.Start();
            cthread2.Start();
            cthread3.Start();
        }
    }
    class ProduceAndConsume
    {
        private int count = 0;
        private int pID=0;
        private int cID = 0;
        private object mutexobjext = new object();
        private Mutex IDmux = new Mutex();//该互斥量是对产品序号的互斥
        private Mutex Countmux = new Mutex();//该互斥量是对公共区产品数量的互斥
        public void produce()
        {
            while (true)
            {
                IDmux.WaitOne();//申请产品序号互斥,不行则等待
                if (pID >= 100)
                {

                    //达到一百个,释放互斥,线程结束
                    IDmux.ReleaseMutex();
                    break;
                }
                Countmux.WaitOne();//申请公共区数量互斥
                if (count >= 5)
                {

                    //公共区满,生产线程释放互斥后睡眠
                    Countmux.ReleaseMutex();
                    IDmux.ReleaseMutex();
                    Thread.Sleep(2);
                    continue;
                }
                else
                {

                       //公共区数量加一,并打印生产产品的序号信息,完成后释放互斥
                        count = count + 1;
                        Countmux.ReleaseMutex();
                        pID = pID + 1;
                        Console.WriteLine("Has produced {0}..", pID);
                        IDmux.ReleaseMutex();
                        Thread.Sleep(1);
                }
            }
        }
        public void consume()
        {

            //类似于produce(),不同是消费过程
            while (true)
            {
                IDmux.WaitOne();
                if(cID>=100)
                {
                    IDmux.ReleaseMutex();
                    break;
                }
                Countmux.WaitOne();
                if (count <= 0)
                {
                    Countmux.ReleaseMutex();
                    IDmux.ReleaseMutex();
                    Thread.Sleep(2);
                    continue;
                }
                else
                {
                        count = count - 1;
                        Countmux.ReleaseMutex();
                        cID = cID + 1;
                        Console.WriteLine("Has Consume {0}", cID);
                        IDmux.ReleaseMutex();
                        Thread.Sleep(1);
                }
            }
        }
    }

      下面是执行结果,可以看到进程已经很好的同步了 :

Has produced 1..
Has produced 2..
Has produced 3..
Has produced 4..
Has produced 5..
Has Consume 1
Has produced 6..
Has Consume 2
Has Consume 3
Has Consume 4
Has produced 7..
Has Consume 5
Has Consume 6
Has produced 8..
Has produced 9..
Has Consume 7
Has produced 10..
Has Consume 8
Has Consume 9
Has Consume 10
Has produced 11..
Has produced 12..
Has Consume 11
Has produced 13..
Has produced 14..
Has produced 15..
Has Consume 12
Has produced 16..
Has Consume 13
Has Consume 14
Has produced 17..
Has produced 18..
Has Consume 15
Has produced 19..
Has Consume 16
Has produced 20..
Has Consume 17
Has produced 21..
Has produced 22..
Has Consume 18
Has Consume 19
Has Consume 20
Has produced 23..
Has Consume 21
Has Consume 22
Has produced 24..
Has Consume 23
Has produced 25..
Has produced 26..
Has Consume 24
Has produced 27..
Has Consume 25
Has Consume 26
Has produced 28..
Has Consume 27
Has Consume 28
Has produced 29..
Has produced 30..
Has Consume 29
Has produced 31..
Has Consume 30
Has Consume 31
Has produced 32..
Has Consume 32
Has produced 33..
Has produced 34..
Has produced 35..
..................................

转载于:https://www.cnblogs.com/yibinboy/archive/2009/12/27/1633077.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379451.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ffplay SDL_OpenAudio (2 channels, 44100 Hz): WASAPI can‘t initialize audio client“

windows下&#xff1a; ffplay 提示"SDL_OpenAudio (2 channels, 44100 Hz): WASAPI can’t initialize audio client" 添加环境变量&#xff1a;SDL_AUDIODRIVERdirectsound

js 正则表达式,正整数

var ss "3.333";var type /^[0-9]*[1-9][0-9]*$/;var re new RegExp(type);alert(ss.match(re));if (ss.match(re) null) {alert("请输入大于零的整数!");return;} 转载于:https://www.cnblogs.com/lingxzg/archive/2012/08/02/2620543.html

java 根据类名示例化类_Java即时类| EpochSecond()方法的示例

java 根据类名示例化类EpochSecond()方法的即时类 (Instant Class ofEpochSecond() method) Syntax: 句法&#xff1a; public static Instant ofEpochSecond(long sec_val);public static Instant ofEpochSecond(long sec_val, long nanos_adjust);ofEpochSecond() method is…

java中Date()类型输入数据的处理

对于Date类型的数据&#xff0c;需要输入生日存入相应数据库中 private Date birthday;// 生日package com.pdsu.mybatis.pojo;import java.io.Serializable; import java.util.Date;public class User implements Serializable {/*** */private static final long serialVers…

(扩展)欧几里德快速幂

GCD模板 __int64 gcd(__int64 a,__int64 b) {return b0? a:gcd(b,a%b); } 欧几里德算法又称辗转相除法&#xff0c;用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理&#xff1a; gcd函数就是用来求(a,b)的最大公约数的。 gcd函数的基本性质&#xff1a; gcd(a,…

汇编语言-002(.data、Equal、$、EQU 、MOV 、MOVSX、MOVZX)

1&#xff1a;变量相加程序 .386 .model flat,stdcall.stack 4096 ExitProcess PROTO,dwExitCode:DWORD.data firstval DWORD 20002000h secondval DWORD 11111111h thirdval DWORD 22222222h sum DWORD 0.code main PROCmov eax,firstvaladd eax,secondvaladd eax,thirdvalm…

\r与\n的区别,\r\n与\n或\r的区别(C语言/C#)

本文出处http://topic.csdn.net/t/20020718/07/882679.html 原作者:triout&#xff08;笨牛&#xff09; \r表示回车&#xff0c;\n表示换行&#xff0c;我们按回车按钮的时候&#xff0c;系统自动产生回车和换行两个字符&#xff1a; 回车仅仅是表示完成&#xff0c;把光…

通过ID查询一个用户的两种开发方法

通过ID查询一个用户的两种开发方法 数据库建表sql语句如下&#xff1a;https://github.com/beyondyanyu/Sayingyy/blob/master/JDBC2-数据库sql建表语句 ①&#xff0c;原始Dao开发&#xff1a; UserDao.java&#xff08;接口&#xff09;: package com.pdsu.mybatis.dao;i…

duration java_Java Duration类| minusMinutes()方法与示例

duration java持续时间类minusMinutes()方法 (Duration Class minusMinutes() method) minusMinutes() method is available in java.time package. minusMinutes()方法在java.time包中可用。 minusMinutes() method is used to subtract the given duration in minutes from t…

Silverlight + WCF异步调用 例子

看大家好像对我的NParsing框架不是很感兴趣&#xff08;写NParsing帖没人顶我&#xff09;&#xff0c;那就给大家来点“甜品”&#xff0c;换换口谓。来说说Silverlight方面的东西。 在Silverlight中数据通信只能用异步。有人会觉得写起来很麻烦&#xff0c;其实不然。也有很简…

我博客主页的搜索功能怎么不好用

用博客里面的搜索功能&#xff0c;“找找看”&#xff0c;搜索我博客里面的关键字&#xff0c;但是不能出现结果。但是我在别人的主页上能够搜索该人的内容&#xff0c;能够查询到记录&#xff0c;难道博客园对每个博客的信息要先排序&#xff1f;目前我的还不在他的搜索数据库…

小议SqlMapConfig.xml配置文件

①、mybatis-3-config.dtd 主要用于mybatis的核心配文件sqlMapConfig.xml的约束 sqlMapConfig.xml代码如下&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN&q…

ffmepg 命令提取音视频数据

原文件&#xff1a; 1&#xff1a; 原音频数据提取&#xff08;保留还是mp4的封装格式的&#xff09;&#xff1a; ffmpeg -i test_1920x1080.mp4 -acodec copy -vn audio.mp4 -vn 就是没有视频&#xff0c; -acodec copy 音频拷贝不进行任何转码 原视频数据提取&#xff0…

Java BigInteger类| modInverse()方法与示例

BigInteger类modInverse()方法 (BigInteger Class modInverse() method) modInverse() method is available in java.math package. modInverse()方法在java.math包中可用。 modInverse() method is used to calculate the mod inverse by using the inverse of (this BigInteg…

【7】jQuery学习——入门jQuery选择器之过滤选择器-可见性过滤选择器

这篇什么都不说&#xff0c;看标题就知道了&#xff0c;很简单&#xff0c;就2个选择器&#xff0c;嘿嘿 选择器描述返回$("Element:hidden")选取所有不可见的元素集合元素$("Element:visible")选取所有可见元素集合元素这篇很简单吧&#xff0c;就2个&…

Creating an undraggable TitleWindow container in Flex (转载)

The following examples show how you can create an undraggable TitleWindow container by setting the isPopUp property to false on the TitleWindow instance. <?xml version"1.0" encoding"utf-8"?><!-- http://blog.flexexamples.com/2…

汇编语言-003(LAHF_SAHF 、XCHG、FLAGS、 OFFSET、ALIGN、PTR、LENGTHOF、SIZEOF)

1&#xff1a;LAHF将EFLAGS符号寄存器低8位字节复制到AH&#xff0c;SAHF将AH复制到EFLAGS符号寄存器低8位字节 .386 .model flat,stdcall.stack 4096 ExitProcess PROTO,dwExitCode:DWORD.data saveflags BYTE ?.code main PROClahfmov saveflags ,ahmov ah,saveflagssahfIN…

Mybatis中的核心配置文件SqlMapConfig.xml详细介绍

一、properties&#xff08;属性&#xff09; 可以引用java属性文件中的配置信息如下 jdbc.properties代码如下&#xff1a; jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/mybatis?characterEncodingutf-8 jdbc.usernameroot jdbc.passwordbeyond…

用Kotlin开发您的第一个应用程序| Android与Kotlin

In the previous article, we learned how to setup Kotlin in the android studio? Now moving to journey ahead we are going to develop our first app with Kotlin. It is the basic app, but it will let you know the structure of the program. 在上一篇文章中&#x…

数据结构与算法分析-第一章Java类(02)

编写一个名为Person的类&#xff0c;它包含分别表示人的名字与年龄的两个数据域。要求此类包含对其中任何一个数据域进行设置与获取的方法。还要求包含可进行下列测试的方法&#xff1a; 两个Person对象是否相等--即是否有相同的名称与年龄一个人是否比另一个人年长 最后&#…