示例#1
0
        public void TryRaceCondition()
        {
            List <Task>  tasks   = new List <Task>();
            BanckAccount account = new BanckAccount();

            Enumerable.Range(1, 30).ToList().ForEach(x => tasks.Add(new Task(() => account.Deposit(100))));
            Enumerable.Range(1, 30).ToList().ForEach(x => tasks.Add(new Task(() => account.Withdraw(100))));

            tasks.ForEach(t => t.Start());
            Task.WaitAll(tasks.ToArray());

            Console.WriteLine(account.Balance);
            tasks.Clear();

            Enumerable.Range(1, 30).ToList().ForEach(x => tasks.Add(new Task(() => account.DepositInterlock(100))));
            Enumerable.Range(1, 30).ToList().ForEach(x => tasks.Add(new Task(() => account.WithdrawInterlock(100))));

            tasks.ForEach(t => t.Start());
            Task.WaitAll(tasks.ToArray());

            Console.WriteLine(account.Balance);
        }
示例#2
0
        public void TryMutex()
        {
            void Transfer(BanckAccount from, BanckAccount to, int amount)
            {
                from.Balance -= amount;
                to.Balance   += amount;
            }

            List <Task> tasks = new List <Task>();

            BanckAccount account1 = new BanckAccount();
            BanckAccount account2 = new BanckAccount();

            Mutex mutex1 = new Mutex();
            Mutex mutex2 = new Mutex();

            tasks.Add(new Task(() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    bool haveLock = mutex1.WaitOne();
                    try { account1.Balance += 1; }
                    finally { if (haveLock)
                              {
                                  mutex1.ReleaseMutex();
                              }
                    }
                }
            }));

            tasks.Add(new Task(() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    bool haveLock = mutex2.WaitOne();
                    try { account2.Balance += 1; }
                    finally { if (haveLock)
                              {
                                  mutex2.ReleaseMutex();
                              }
                    }
                }
            }));

            // Transfer needs to lock both accounts
            Enumerable.Range(1, 10).ToList().ForEach(x => tasks.Add(new Task(() =>
            {
                bool haveLock = Mutex.WaitAll(new[] { mutex1, mutex2 });
                try
                {
                    Transfer(account1, account2, 100);
                }
                finally { if (haveLock)
                          {
                              mutex1.ReleaseMutex(); mutex2.ReleaseMutex();
                          }
                }
            })));

            tasks.ForEach(t => t.Start());
            Task.WaitAll(tasks.ToArray());

            Console.WriteLine(account1.Balance);
            Console.WriteLine(account2.Balance);
        }