У меня есть объект 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;
}
}
Кажется простым, но есть больше битов кода, использующих обе блокировки, чем только в этом примере, и я знаю из предыдущего опыта, что, если несколько фрагментов кода требуют одинаковых общих блокировок, они имеют риск взаимоблокировки.
Какой хороший способ избежать этого?
Может быть, есть какой-то механизм, который позволит мне атомарно блокировать два объекта?