这个简单的代码应该会产生死锁,但事实并非如此

发布于 2024-12-10 17:11:18 字数 443 浏览 0 评论 0原文

类似于我昨天发布的问题,我有这个问题我就是无法理解。代码非常简单,(我认为)应该会产生死锁。我什至将账户数量减少到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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云之铃。 2024-12-17 17:11:18

问题出在这一行:

mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

基本上,只有一个 Account 对象,但有很多对它的引用。因此你只能锁定一个对象。

如果您创建许多不同的 Account 对象,您应该能够很快看到死锁。

Problem is on this line:

mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

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.

棒棒糖 2024-12-17 17:11:18

唯一拥有“竞争”资源的地方是在 fromaccount 上同步,然后在 toaccount 上同步 - 其他一切都仅取决于一个锁。

如果您有另一个方法在 toaccount 上同步,然后在 fromaccount 上同步,您可能有机会导致死锁,但就目前的代码而言,它应该表现得非常好。

The only place where you have a 'contested' resource is where you synchronize on fromaccount and then on toaccount - everything else depends on one lock only.

If you had another method which synchronized on toaccount and then on fromaccount you might have a chance of causing deadlock, but as the code currently is it should be perfectly well-behaved.

小嗲 2024-12-17 17:11:18

我认为您需要在 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.

牵你的手,一向走下去 2024-12-17 17:11:18
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29

您最终会得到对同一对象的 2 个引用的列表。

该对象一次只能被一个线程锁定。你永远不会陷入僵局。

我假设您想使用 Account 类的 2 个不同实例来初始化 mAccounts。

mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文