这个简单的代码应该会产生死锁,但事实并非如此
类似于我昨天发布的问题,我有这个问题我就是无法理解。代码非常简单,(我认为)应该会产生死锁。我什至将账户数量减少到2个,以增加死锁的概率。
代码确实很容易理解,但需要提供一些上下文。我有一家有账户的银行,并且我在账户之间进行大量转账。传输方法应该会产生死锁。为什么没有发生这种情况?
我只能认为代码运行得太快了,但这似乎不太可能一直发生。
这是整个代码: http://pastebin.com/HWJpuT38
Similar to the question I posted yesterday, I have this problem that I just can't understand. The code is pretty simple and should (I think) generate a deadlock. I even reduced the number of accounts to 2, to increase the probability of deadlocks.
The code is really easy to understand but to put some context. I have a bank with accounts and I'm doing lots of transfers between accounts. The transfer method should generate a deadlock. Why isn't that happening?
I can only think that the code is running way too fast, but that seems improbable to happen all the time.
Here's the whole code:
http://pastebin.com/HWJpuT38
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题出在这一行:
基本上,只有一个
Account
对象,但有很多对它的引用。因此你只能锁定一个对象。如果您创建许多不同的
Account
对象,您应该能够很快看到死锁。Problem is on this line:
Basically, there is only one
Account
object, but lots of references to it. Thus you're only ever locking on a single object.If you create lots of different
Account
objects, you should be able to see the deadlock quite quickly.唯一拥有“竞争”资源的地方是在
fromaccount
上同步,然后在toaccount
上同步 - 其他一切都仅取决于一个锁。如果您有另一个方法在
toaccount
上同步,然后在fromaccount
上同步,您可能有机会导致死锁,但就目前的代码而言,它应该表现得非常好。The only place where you have a 'contested' resource is where you synchronize on
fromaccount
and then ontoaccount
- everything else depends on one lock only.If you had another method which synchronized on
toaccount
and then onfromaccount
you might have a chance of causing deadlock, but as the code currently is it should be perfectly well-behaved.我认为您需要在
AccountTransferRunnable
中的循环中添加某种睡眠,否则调度程序将运行该线程直到结束,然后再启动另一个线程。通过睡眠,您将使调度程序有机会切换到另一个线程(如果第一个线程仍在运行),这将使您的代码有机会陷入死锁。
I think you need to add some sort of sleep to your loop in
AccountTransferRunnable
otherwise the Scheduler will run the thread until end before starting the other one.With a Sleep you will give the Scheduler the chance to switch to the other thread will the first one is still running, which will give your code the chance to run into a deadlock.
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29
您最终会得到对同一对象的 2 个引用的列表。
该对象一次只能被一个线程锁定。你永远不会陷入僵局。
我假设您想使用 Account 类的 2 个不同实例来初始化 mAccounts。
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29
You end up with a list of 2 references to the same object.
That object can only be locked by one thread at a time. You can never have a deadlock.
I assume you wanted to initialize mAccounts with 2 different instances of Account class.