与问题I posted yesterday类似,我遇到了这个我无法理解的问题。代码非常简单,应该(我认为)会产生死锁。我甚至将帐号数量减少到2,以增加死锁的可能性。
代码很容易理解,但是要提供一些上下文。我有一个账户银行,我在账户之间进行大量转账。传输方法应该生成死锁。为什么不发生这种情况?
我只能认为代码运行速度太快,但似乎不太可能一直。
这是整个代码: http://pastebin.com/HWJpuT38
答案 0 :(得分:8)
问题出在这一行:
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
基本上,只有一个Account
对象,但很多引用它。因此,您只能锁定单个对象。
如果你创建了许多不同的Account
对象,你应该能够很快看到死锁。
答案 1 :(得分:0)
您拥有“有争议”资源的唯一地方是您在fromaccount
上然后在toaccount
上同步的地方 - 其他一切只依赖于一个锁定。
如果你有另一个方法在toaccount
然后在fromaccount
上同步,你可能会导致死锁,但是正如代码当前它应该是完全正常的。
答案 2 :(得分:0)
我认为您需要在AccountTransferRunnable
中为循环添加某种睡眠,否则调度程序将运行该线程直到结束,然后再启动另一个。
使用Sleep会让Scheduler有机会切换到第一个仍在运行的另一个线程,这会让你的代码有机会遇到死锁。
答案 3 :(得分:0)
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
您最终得到了对同一对象的2个引用列表。
该对象一次只能被一个线程锁定。你永远不会陷入僵局。
我假设你想用2个不同的Account类实例初始化mAccounts。