java - 如何避免容易陷入僵局?

标签 java locking deadlock

我有一个对象 User,它有两个锁:inventoryLock 和currencyLock。通常这些锁会单独使用,例如

synchronized (user.inventoryLock) {

 // swap items
 tmp = user.inventory[x];
 user.inventory[x] = user.inventory[y];
 user.inventory[y] = tmp;

}

synchronized (user.currencyLock) {

 if (user.money < loss) throw new Exception();
 user.money -= loss;

}

但有时一段代码需要两个锁:

synchronized (user.currencyLock) {
 synchronized (user.inventoryLock) {

  if (user.money < item.price) throw new Exception();
  user.money -= item.price;
  user.inventory[empty] = item;

 }
}

看起来很简单,但是使用这两个锁的代码比这个例子要多,而且我从以前的经验知道,如果多段代码需要相同的共享锁,它们就有死锁的风险。

有什么好方法可以避免这种情况?

是否有某种机制可以让我自动锁定两个对象?

最佳答案

始终先锁定一个锁,再锁定另一个锁,死锁的要求之一是循环等待模式

例如,如果您可以确保在锁定 inventoryLock 之前始终锁定 currencyLock,并且在您已经拥有 currencyLock 时绝不尝试锁定 currencyLock inventoryLock你会没事的

关于java - 如何避免容易陷入僵局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7986430/

相关文章:

android - 如何检测是否需要 PIN/密码/图案来解锁手机?

locking - log4net RollingFileAppender 间歇性锁定文件问题

android - 当我在解锁前更改锁定屏幕的方向时,应用程序被杀死

sql - 为什么 SQL Server 死锁受害者错误 (1205) 会结束其所有事务?

java - JLabel Icon 未使用 setIcon (或其他冗余)更新

java - 在测试中发送交易实际上并没有减少余额

java - 从 AWS Java SDK 2.0 中的 GetObjectResponse 获取 S3Object

java - Jasper API 仅打印第一个报告,其他报告打印为空白

sql-server - 添加主键标识列可以解决死锁问题吗?

c# - 在关闭表单之前等待任务完成