银行情况出现僵局问题
我有一个问题,我无法解决这个问题
void Transfer(Account a, Account b, decimal amount)
{
lock (a) {
lock (b) {
if (a.Balance < amount)
throw new InsufficientFundsExc();
a.Balance -= amount;
b.Balance += amount;
}
}
}
,问题是“这是银行帐户之间的转账。”lock(...)”结构用于对抗竞争条件。这是什么问题?您提出什么解决方案?可以你帮我吗?
I have a problem, i cannot resolve this problem
void Transfer(Account a, Account b, decimal amount)
{
lock (a) {
lock (b) {
if (a.Balance < amount)
throw new InsufficientFundsExc();
a.Balance -= amount;
b.Balance += amount;
}
}
}
and question is " this is a transfer between bank accounts. "lock(...)" structure is used against race condition. What is this problem? and what solution do you propose? CAN YOU HELP ME?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您在从 B 到 A 的转账的同时进行从 A 到 B 的转账,则可能会出现死锁,因为您没有锁定订单。
但是为什么这段代码首先是多线程的呢?
您需要始终按照相同的顺序取锁。例如,为每个锁提供一个整数 ID,并始终首先锁定较低的 ID。
if you have a transfer from A to B at the same time as a transfer from B to A it can deadlock because you have no lock order.
But why the hell is this code multithreaded in the first place?
You need to take your locks always in the same order. For example by giving each lock an integer Id and always locking the lower ID first.
如果您可以对帐户进行排序(通过 ID 号或其他方式),您始终可以先锁定 ID 较低的帐户。这将确保没有线程尝试在另一个线程先锁定
a
然后b
的同时先锁定a
然后b
>,因为它们都会首先锁定a
。If you can order the accounts (by ID number or something), you can always lock the one with the lower ID first. This will ensure that no thread tries to lock
a
thenb
at the same time as another thread lockinga
thenb
, as they will both locka
first.死锁
Transfer(a,b,10.0) 时发生 ;和传输(b,a,10.0);同时被调用
第一次调用将锁定
那么第二个可以在第一个锁定 a 之前锁定 b
都无法继续 ->僵局
deadlock
when Transfer(a,b,10.0); and Transfer(b,a,10.0); are called simultaneously
the first call will lock a
then the second can lock b before the first can lock a
and neither can continue -> deadlock
正如 CodeInChaos 所暗示的那样,您的问题是潜在的死锁。如果您不明白什么是死锁,那么我建议您阅读维基百科上的哲学家就餐问题。
本文实际解释了该问题,并提出了一些解决方案,包括使用锁定顺序。
编辑:
为了进一步将您的问题与本文联系起来,银行帐户是分叉(即只能独占使用的共享资源,因此需要锁定),访问代码的线程是哲学家(即不时需要使用的实体)可锁定资源)。
As CodeInChaos suggests, your problem is a potential deadlock. If you don't understand what a deadlock is then I recommend reading the dining philosophers problem on Wikipedia.
The article explains the problem in real terms and suggests some solutions including using a locking order.
Edit:
To further relate your problem to the article, the bank accounts are forks (i.e. shared resources that can only be used exclusively therefore need to be locked) and the threads accessing the code are the philosophers (i.e. entities that from time to time require the use of lockable resources).
@RatchetFreak 对于为什么会发生这种情况的回答一针见血。我认为您遇到的主要问题是锁是一个非常低级别的构造,这使得很难理智地考虑线程场景。
我建议(如果可能的话)使用一组稍高级别的构造来让自己的生活更轻松。 Daniel Chamber 在他的库中提供了一套很好的轻量级实用程序。
@RatchetFreak hit the nail on the head with his response regarding why this has occured. I think the main problem that you are having it that a lock is a very low level construct which makes it difficult to think about threading scenario's sanely.
I would recommend (if possible) to use a set of slightly higher level constructs to make life easier on yourself. Daniel Chamber's has a good light weight set of utilities for this in his library.
想象一下,两个非常固执的女士和她们的丈夫一起去度假屋。第二天早上他们醒来,发现那些人已经走了。剩下的唯一衣服:一条裙子和一件衬衫(似乎其中一个男人喜欢穿女装 - 可以解释很多)。女士们意识到需要去买东西——食物、衣服、新丈夫。她们都想“好吧,我穿上衣服就走”,一个穿上裙子,另一个穿上衬衫。他们看到了发生的事情,但每个人都太固执,无法改变他们的计划(而且太害羞,不敢半裸出去)。他们的固执就像一台愚蠢的计算机遵循着“当时看起来不错”的程序。他们不能/不会自动修改他们在遇到“运行时错误”时所采取的看似明智的方法,因此他们都注定要饿死。这是一个死锁:等待你无法获得的资源,因为有人在等待你自己占用的资源。
如果有更多的远见和计划,他们本可以找到一种策略来确保他们中的一个人逃脱。例如:
等等。
Imagine two very stubborn ladies went to a holiday house with their husbands. They woke the next morning and found the men gone. The only clothes left: a skirt and a shirt (seems one of the men liked wearing women's clothing - could explain a lot). The ladies realise the need to go get stuff - food, clothes, new husbands. They both think "well, I'll put the clothes on and go", and one puts on the skirt while the other dons the shirt. They see what's happened but each is too stubborn to change their plan (and way too shy to go out half naked). Their stubbornness is akin to a dumb computer following a program that "looked good at the time". They can't/won't automatically revise the seemingly sensible approach they had above on hitting a "run-time error", so they are both doomed to starve to death. That's a dead lock: waiting for resources you can't get because someone's waiting for what you're hogging yourself.
With a bit more foresight and planning, they could have found a strategy that would make sure one of them got out. For example:
etc.