From 52d5665fc022a6765456fa3c2965c8492516c1a0 Mon Sep 17 00:00:00 2001 From: Matin Date: Sun, 14 Jun 2026 04:07:46 +0430 Subject: [PATCH 1/2] implement bankAccount + bonus --- .idea/.gitignore | 10 +++ .idea/compiler.xml | 13 ++++ .idea/encodings.xml | 7 ++ .idea/jarRepositories.xml | 20 ++++++ .idea/misc.xml | 12 ++++ .idea/vcs.xml | 7 ++ .../java/dev/banking/model/BankAccount.java | 70 +++++++++++++++++-- 7 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..812c3f9 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b83499c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..8306744 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/java/dev/banking/model/BankAccount.java b/src/main/java/dev/banking/model/BankAccount.java index 745ede2..f76857a 100644 --- a/src/main/java/dev/banking/model/BankAccount.java +++ b/src/main/java/dev/banking/model/BankAccount.java @@ -1,10 +1,14 @@ package dev.banking.model; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.locks.Condition; public class BankAccount { private final int accountId; private long balance; - + private final ReentrantLock lock = new ReentrantLock(); + private final Condition sufficientFunds = lock.newCondition(); /* * Students may introduce additional fields * such as: @@ -31,8 +35,16 @@ public class BankAccount { * - 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"); + public long getBalance() + { + lock.lock(); + try{ + return this.balance ; + }finally { + lock.unlock(); + } + + } /* @@ -42,8 +54,16 @@ public class BankAccount { * Requirements: * - Must not lose updates under concurrency */ + public void deposit(long amount) { - throw new UnsupportedOperationException("TODO: implement thread-safe deposit"); + if (amount <= 0) return; + lock.lock(); + try { + this.balance += amount ; + + }finally { + lock.unlock(); + } } /* @@ -56,7 +76,21 @@ public class BankAccount { * to extend the system (optional) */ public void withdraw(long amount) { - throw new UnsupportedOperationException("TODO: implement thread-safe withdraw"); + + lock.lock(); + try { + while (this.balance < amount ) + { + try { + sufficientFunds.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + this.balance -= amount ; + }finally { + lock.unlock(); + } } /* @@ -73,6 +107,30 @@ public class BankAccount { * - Or tryLock with retry strategy */ public void transfer(BankAccount target, long amount) { - throw new UnsupportedOperationException("TODO: implement atomic deadlock-free transfer"); + if (target == null || amount <= 0 || target.accountId == this.accountId ) return; + BankAccount firstAccount ; + BankAccount secondAccount ; + if (this.accountId < target.accountId ) + { + firstAccount = this ; + secondAccount = target ; + } + else { + firstAccount = target ; + secondAccount = this ; + } + firstAccount.lock.lock(); + try { + secondAccount.lock.lock(); + try { + this.balance -= amount ; + target.balance += amount ; + }finally { + secondAccount.lock.unlock(); + } + }finally { + firstAccount.lock.unlock(); + } + } } \ No newline at end of file -- 2.54.0 From 85950c58c4b7a649e42286d83800ac11b9d1cb65 Mon Sep 17 00:00:00 2001 From: Matin Date: Sun, 14 Jun 2026 05:06:32 +0430 Subject: [PATCH 2/2] Answer the question and write a bonus simple example about an atomic variable --- Answers.md | 0 src/main/java/dev/banking/model/bonus.java | 32 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 Answers.md create mode 100644 src/main/java/dev/banking/model/bonus.java diff --git a/Answers.md b/Answers.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/dev/banking/model/bonus.java b/src/main/java/dev/banking/model/bonus.java new file mode 100644 index 0000000..8063c75 --- /dev/null +++ b/src/main/java/dev/banking/model/bonus.java @@ -0,0 +1,32 @@ +package dev.banking.model; +import java.util.concurrent.atomic.AtomicInteger ; +public class bonus { + private static int normalVariable = 0 ; + private static final AtomicInteger atomicVariable = new AtomicInteger(0) ; + public static void main(String[] args) throws InterruptedException{ + int numberOfThrad = 10 ; + int incrementsPerThread = 10000 ; + Thread[] threads = new Thread[numberOfThrad] ; + Runnable task = () -> { + for (int i = 0 ; i < incrementsPerThread ; i ++ ) + { + normalVariable ++ ; + atomicVariable.incrementAndGet() ; + } + }; + for (int i = 0 ; i < numberOfThrad ; i ++) + { + threads[i] = new Thread(task) ; + threads[i].start(); + } + for (Thread thread : threads) + { + thread.join(); + } + System.out.println("Expected Value (مقدار مورد انتظار): " + (numberOfThrad * incrementsPerThread)); + System.out.println("Normal Integer Result (متغیر معمولی): " + normalVariable); + System.out.println("Atomic Integer Result (متغیر اتمیک): " + atomicVariable.get()); + + } + +} -- 2.54.0