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的时候才能执行(信号量改变的时候会有机制唤醒正在等待的线程,我猜的.....)


原文地址:https://www.cnblogs.com/muyoucai/p/6257112.html