Лучшее решение вместо вложенных синхронизированных блоков в Java?

У меня есть класс Bank со списком Account . В банке есть метод transfer () для перевода стоимости с одного счета на другой. Идея состоит в том, чтобы заблокировать учетные записи из и в во время передачи.

Для решения этой проблемы у меня есть следующий код (имейте в виду, что это очень тривиальный пример, потому что это всего лишь пример):

public class Account {
    private int mBalance;

    public Account() {
        mBalance = 0;
    }

    public void withdraw(int value) {
        mBalance -= value;
    }

    public void deposit(int value) {
        mBalance += value;
    }
}

public class Bank {
    private List<Account> mAccounts;
    private int mSlots;

    public Bank(int slots) {
        mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
        mSlots = slots;
    }

    public void transfer(int fromId, int toId, int value) {
        synchronized(mAccounts.get(fromId, toId)) {
            synchronized(mAccounts.get(toId)) {
                mAccounts.get(fromId).withdraw(value);
                mAccounts.get(toId).deposit(value);
            }
        }
    }
}

Это работает, но не предотвращает взаимоблокировок . Чтобы исправить это, нам нужно изменить синхронизацию на следующее:

synchronized(mAccounts.get(Math.min(fromId, toId))) {
    synchronized(mAccounts.get(Math.max(fromId, toId))) {
        mAccounts.get(fromId).withdraw(value);
        mAccounts.get(toId).deposit(value);
    }
}

Но компилятор предупреждает меня о вложенных блоках синхронизации , и я полагаю, что это плохо? Кроме того, мне не очень нравится решение max / min (я не был тем, кто придумал эту идею), и я бы хотел избежать этого, если это возможно.

Как бы исправить эти 2 проблемы, указанные выше? Если бы мы могли заблокировать более одного объекта, мы бы заблокировали как из , так и в учетную запись, но мы не можем этого сделать (насколько мне известно). Какое же тогда решение?

9
задан Ricardo Amaral 19 October 2011 в 23:04
поделиться