diff --git a/src/main/java/dev/banking/model/BankAccount.java b/src/main/java/dev/banking/model/BankAccount.java index 745ede2..746f73d 100644 --- a/src/main/java/dev/banking/model/BankAccount.java +++ b/src/main/java/dev/banking/model/BankAccount.java @@ -1,9 +1,13 @@ package dev.banking.model; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + public class BankAccount { private final int accountId; private long balance; + private Lock lock = new ReentrantLock(); /* * Students may introduce additional fields @@ -23,44 +27,44 @@ public class BankAccount { return accountId; } - /* - * TODO: - * Return the current balance in a thread-safe way. + /* Return the current balance in a thread-safe way. * * Requirements: * - Must be safe under concurrent reads/writes * - Should not block unnecessarily if using read/write locks */ public long getBalance() { - throw new UnsupportedOperationException("TODO: implement thread-safe balance read"); + + lock.lock(); + try{ + return balance; + } + finally { + lock.unlock(); + } } - /* - * TODO: - * Increase balance atomically. + /* Increase balance atomically. * * Requirements: * - Must not lose updates under concurrency */ - public void deposit(long amount) { - throw new UnsupportedOperationException("TODO: implement thread-safe deposit"); + public synchronized void deposit(long amount) { + balance += amount; } - /* - * TODO: - * Decrease balance atomically. + /* Decrease balance atomically. * * Requirements: * - Must not cause race conditions * - Negative balance handling is NOT required unless you decide * to extend the system (optional) */ - public void withdraw(long amount) { - throw new UnsupportedOperationException("TODO: implement thread-safe withdraw"); + public synchronized void withdraw(long amount) { + balance -= amount; } /* - * TODO: * Transfer money between two accounts atomically. * * IMPORTANT REQUIREMENTS: @@ -73,6 +77,33 @@ public class BankAccount { * - Or tryLock with retry strategy */ public void transfer(BankAccount target, long amount) { - throw new UnsupportedOperationException("TODO: implement atomic deadlock-free transfer"); + + BankAccount first, second; + + if(target == this) return; + + if (this.getAccountId() < target.getAccountId()) { + first = this; + second = target; + } + else { + first = target; + second = this; + } + + first.lock.lock(); + try { + second.lock.lock(); + try { + this.withdraw(amount); + target.deposit(amount); + } + finally { + second.lock.unlock(); + } + } + finally { + first.lock.unlock(); + } } } \ No newline at end of file