zoukankan      html  css  js  c++  java
  • C#线程同步控制

    ManualResetEvent类,用于通知一个或多个正在等待的线程已发生事件,它有2种状态:有信号(true)的无信号(false)。

    有2种方法可以设置它的信号状态:构造函数构造的时候设置或者通过对象方法设置:

    ManualResetEvent mutex=new ManualResetEvent(true/false);//初始化一种状态
    mutex.Reset();//设置mutex为无信号
    mutex.Set();//设置mutex为有信号

    多线程同步控制例子:

    namespace BankTransfering2
    {
        class Bank
        {
            private double account1 = 2500;
            private double account2 = 1000;
            ManualResetEvent[] mres = { new ManualResetEvent(false), 
                                        new ManualResetEvent(false) 
                                      };  //创建包含两个ManualResetEvent类对象的数组
    
    
            public void transfering()    //将100元从帐户account1转到帐户account2
            {
                mres[0].Reset();
                account1 = account1 - 100;
                Thread.Sleep(100);
                account2 = account2 + 100;
                mres[0].Set();
            }
            public void transfering2()    //将300元从帐户account2转到帐户account1
            {
                mres[1].Reset();
                account1 = account1 + 300;
                Thread.Sleep(200);
                account2 = account2 - 300;
                mres[1].Set();
            }
            public void querying()    //查询帐户account1和account2上的余额
            {
                mres[0].WaitOne();//等待transfering的信号
                mres[1].WaitOne();//等待transfering2的信号
           //只有当2个信号都为true时,说明它们都运行完了,这个时候query才运行
                //WaitHandle.WaitAll(mres);
                Console.WriteLine("帐户account1上的余额为:{0} 元", account1);
                Console.WriteLine("帐户account2上的余额为:{0} 元", account2);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Bank a = new Bank();
                Thread user1 = new Thread(new ThreadStart(a.transfering));      //转帐用户1
                Thread user2 = new Thread(new ThreadStart(a.transfering2));     //转帐用户2
                Thread user3 = new Thread(new ThreadStart(a.querying));     //查账用户
                user1.Start();        //执行转帐(account1到account2)
                user2.Start();         //执行转帐(account2到account1)
                user3.Start();         //查账用户
                Console.ReadKey();
            }
        }
    }

    account1要向account2转钱,transfering是1转向2,transfering2是2转向1。query是查询两人账户状态。

    三条线程并发执行的时候,查询操作必须要等transfering和transfering2都没有在执行动作的时候才能准确查到账户余额,transfering和transfering2在执行操作的时候对相应的信号量置为false,执行完动作后又将其置为true。而query必须要等两个信号量为true的时候才能执行(信号量改变的时候会有机制唤醒正在等待的线程,我猜的.....)

    
    
  • 相关阅读:
    剑指offer二十二之从上往下打印二叉树
    剑指offer二十一之栈的压入、弹出序列
    Hadoop简介与伪分布式搭建—DAY01
    getopt解析命令行参数一例:汇集多个服务器的日志
    软件开发:如何表达和维护大型逻辑
    编程语言与可复用性
    危险的 SQL
    谁终将点燃闪电,必长久如云漂泊
    如何使错误日志更加方便排查问题
    生活的诀窍:任务激励式学习法和短小目标法
  • 原文地址:https://www.cnblogs.com/muyoucai/p/6257112.html
Copyright © 2011-2022 走看看