【发布时间】:2018-07-05 04:51:56
【问题描述】:
我对使用 C# lock 构造的一件事感兴趣
现在来自 MSDN 的示例,然后是主要问题:
以下示例使用线程和锁。只要 lock 语句存在,语句块就是临界区,balance 永远不会变成负数。
class Account
{
private Object thisLock = new Object();
int balance;
Random r = new Random();
public Account(int initial)
{
balance = initial;
}
int Withdraw(int amount)
{
// This condition never is true unless the lock statement
// is commented out.
if (balance < 0)
{
throw new Exception("Negative Balance");
}
// Comment out the next line to see the effect of leaving out
// the lock keyword.
lock (thisLock)
{
if (balance >= amount)
{
Console.WriteLine("Balance before Withdrawal : " + balance);
Console.WriteLine("Amount to Withdraw : -" + amount);
balance = balance - amount;
Console.WriteLine("Balance after Withdrawal : " + balance);
return amount;
}
else
{
return 0; // transaction rejected
}
}
}
public void DoTransactions()
{
for (int i = 0; i < 100; i++)
{
Withdraw(r.Next(1, 100));
}
}
}
class Test
{
static void Main()
{
Thread[] threads = new Thread[10];
Account acc = new Account(1000);
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(acc.DoTransactions));
threads[i] = t;
}
for (int i = 0; i < 10; i++)
{
threads[i].Start();
}
//block main thread until all other threads have ran to completion.
foreach (var t in threads)
t.Join();
}
}
我不明白为什么使用lock 帐户余额不会减负;它总是以0 余额结束编译。
P.S 对不起我的英语。
【问题讨论】:
-
请记住
Random不是线程安全的,因此您也不能在lock之外使用它。 -
值得注意的是,如果您将
for (int i = 0; i < 100; i++)更改为for (int i = 0; i < 2; i++),您的程序将以正余额结束。绝大多数for循环在计数到 100 时是空操作,因为余额已经为零。
标签: c# multithreading