package dev.banking.model; import java.util.concurrent.locks.ReentrantLock; public class BankAccount { private final int accountId; private long balance; private final ReentrantLock lock = new ReentrantLock(); public BankAccount(int accountId, long initialBalance) { this.accountId = accountId; this.balance = initialBalance; } public int getAccountId() { return accountId; } public long getBalance() { lock.lock(); try { return balance; } finally { lock.unlock(); } } public void deposit(long amount) { lock.lock(); try { balance += amount; } finally { lock.unlock(); } } public void withdraw(long amount) { lock.lock(); try { balance -= amount; } finally { lock.unlock(); } } /* * Lock ordering by accountId prevents deadlock: * both A->B and B->A transfers always acquire the * lower-id lock first, so no circular wait can form. */ public void transfer(BankAccount target, long amount) { BankAccount first = this.accountId < target.accountId ? this : target; BankAccount second = this.accountId < target.accountId ? target : this; first.lock.lock(); try { second.lock.lock(); try { this.balance -= amount; target.balance += amount; } finally { second.lock.unlock(); } } finally { first.lock.unlock(); } } }