模拟10个线程,每个线程模拟100次取钱:
其实就是相当于1000个人来同时取钱。当然实际情况是取钱的人分布在不同的地区的取款机取钱。同一个取款机只能一个人操作。
关键是要保证取钱的余额要准确,不能在多人同时操作的时候计算失误,于是要在计算余额的时候锁住。lock关键作用在于此。
static void test() { //初始化10个线程 System.Threading.Thread[] threads = new System.Threading.Thread[10]; //把balance初始化设定为1000 Account acc = new Account(1000); for (int i = 0; i < 10; i++) { System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(acc.DoTransactions)); threads[i] = t; threads[i].Name = "Thread" + i.ToString(); } for (int i = 0; i < 10; i++) { threads[i].Start(); } } public class Account { private Object thisLock = new object(); int balance; Random r = new Random(); public Account(int initial) { balance = initial; } int WithDraw(int amount) { if (balance <= 0) { Console.WriteLine("no Balance........."); return balance; } //确保只有一个线程使用资源,一个进入临界状态,使用对象互斥锁,10个启动了的线程不能全部执行该方法 lock (thisLock) { if (balance >= amount) { Console.WriteLine("----------------------------:" + System.Threading.Thread.CurrentThread.Name + "---------------"); Console.WriteLine("调用Withdrawal之前的Balance:" + balance); Console.WriteLine("把Amount输入 Withdrawal :-" + amount); //如果没有加对象互斥锁,则可能10个线程都执行下面的减法,加减法所耗时间片段非常小,可能多个线程同时执行,出现负数。 balance = balance - amount; Console.WriteLine("调用Withdrawal之后的Balance :" + balance); } else { Console.WriteLine("balance too low :"+balance +"------------>you want amount:"+ amount ); //最终结果 } return balance; } } public void DoTransactions() { for (int i = 0; i < 100; i++) { //生成balance的被减数amount的随机数 var balance= WithDraw(r.Next(1, 100)); if (balance <= 0) { break; } } } }