从多线程角度看,下面的代码有无问题?
class Account
    {
        int balance;
        Random r = new Random();        public Account(int initial)
        {
            balance = initial;
        }        int Withdraw(int amount)
        {
            if (balance < 0)
            {
                throw new Exception("Negative Balance");
            }            Console.WriteLine("Current Thread:" + System.Threading.Thread.CurrentThread.Name);
            if (balance >= amount)
            {
                balance = balance - amount;
                Console.WriteLine(balance);
                return amount;
            }
            else
            {
                return 0;
            }
        }
        internal void DoTransactions()
        {
            Withdraw(r.Next(-100,100));
        }
    }
class Simple
    {            System.Threading.Thread[] threads = new System.Threading.Thread[100];            Account acc = new Account(0);
            for (int i = 0; i < 100; i++)
            {
                threads[i] = new System.Threading.Thread(new System.Threading.ThreadStart(acc.DoTransactions));
                threads[i].Name = "Thread" + i.ToString();
            }
            for (int i = 0; i < 100; i++)
            {
                threads[i].Start();
            }
}书上面说可能会执行到if (balance < 0)
            {
                throw new Exception("Negative Balance");
            }, 所以有问题,要用lock.
但是我的机器上跑了N遍,从来没有执行到抛出异常代码啊。。 WHY?

解决方案 »

  1.   

    上面的解释..internal int Withdraw(int amount)
      {
      if (balance < 0)
      {
        file://如果balance小于0则抛出异常
        throw new Exception(”Negative Balance”);
      }
      //下面的代码保证在当前线程修改balance的值完成之前
      //不会有其他线程也执行这段代码来修改balance的值
      //因此,balance的值是不可能小于0的
      lock (this)
      {
        Console.WriteLine(”Current Thread:”+Thread.CurrentThread.Name);
        file://如果没有lock关键字的保护,那么可能在执行完if的条件判断之后
        file://另外一个线程却执行了balance=balance-amount修改了balance的值
        file://而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了
        file://但是,这个线程却继续执行balance=balance-amount,所以导致balance可能小于0
        if (balance >= amount)
        {
        Thread.Sleep(5);
        balance = balance – amount;
        return amount;
        }
        else
        {
        return 0; // transaction rejected
        }
      }
      }