#264 Deadlock During Transfers Between Wallets

Companies:
T-Bank
Themes:
JavaConcurrencyCode Review

What will be printed? Perform a code review:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        /*
         * Each wallet is represented by one int value: its balance.
         * Initially, create a list of 10 wallets, each with a balance of 100.
         */
        List<Wallet> wallets = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            wallets.add(new Wallet(100));
        }

        ExecutorService executor = Executors.newFixedThreadPool(100);
        for (int i = 0; i < 100000; i++) {
            /*
             * Transfer all money from one wallet to another.
             * Consecutive wallets are selected for every transfer:
             * always transfer from wallet 1 to wallet 2, from wallet 2 to wallet 3, and so on.
             * Always transfer from the last wallet to the first one.
             */
            Wallet wallet1 = wallets.get(i % wallets.size());
            Wallet wallet2 = wallets.get((i + 1) % wallets.size());
            executor.execute(() -> transfer(wallet1, wallet2));
        }

        executor.shutdown(); // Does not cancel already submitted exercises
        executor.awaitTermination(1, TimeUnit.DAYS); // Waits for all submitted exercises to complete

        /*
         * Calculate the sum of all wallet balances and print it.
         * Without the preceding loop, the expected output would be 1000
         * because there were initially 10 wallets with 100 coins each.
         */
        int sum = wallets.stream().mapToInt(wallet -> wallet.balance).sum();
        System.out.println(sum);
    }

    private static void transfer(Wallet wallet1, Wallet wallet2) {
        synchronized (wallet1) {
            synchronized (wallet2) {
                wallet2.balance += wallet1.balance;
                wallet1.balance = 0;
            }
        }
    }

    private static class Wallet {
        public int balance;

        public Wallet(int balance) {
            this.balance = balance;
        }
    }
}

Question review

Mentor
Answer as you would in a real interview. I’ll ask follow-up questions, then compare your answer with the reference answer and show your accuracy as a %.
Sign in to start the dialogue The mentor keeps the context of the current question and your previous messages.
Sign in