Sobes.tech
Senior
39

Задача на многопоточность: зависнет ли программа с переводами между кошельками? Почему?

Companies where asked
Т-БанкТ-Банк

Answer from AI

sobes.tech AI

Зависнет ли программа при переводах между кошельками, зависит от реализации синхронизации и порядка блокировок.

Если при переводе средств между двумя кошельками используется блокировка ресурсов (например, synchronized или ReentrantLock) и потоки захватывают блокировки в разном порядке, может возникнуть взаимная блокировка (deadlock). Например:

  • Поток A блокирует кошелёк 1 и пытается заблокировать кошелёк 2.
  • Поток B блокирует кошелёк 2 и пытается заблокировать кошелёк 1.

Оба потока ждут освобождения ресурсов друг друга — программа зависает.

Чтобы избежать этого, нужно:

  • Всегда захватывать блокировки в одном и том же порядке (например, по ID кошелька).
  • Использовать таймауты при попытке захвата блокировки.
  • Применять высокоуровневые конструкции, например, транзакции или атомарные операции.

Пример безопасного подхода:

int first = Math.min(walletFrom.getId(), walletTo.getId());
int second = Math.max(walletFrom.getId(), walletTo.getId());

synchronized (getWalletById(first)) {
    synchronized (getWalletById(second)) {
        // перевод средств
    }
}

Таким образом, программа не зависнет из-за взаимных блокировок.