From 052a48dddbfbd3fdd2603a918023c9b8bf5c9042 Mon Sep 17 00:00:00 2001 From: 2025mohseni Date: Thu, 4 Jun 2026 08:42:42 +0330 Subject: [PATCH] exercises : Solve multithreading --- .../exercises/DeadlockPreventionWorkshop.java | 23 ++++++------- .../java/workshop/exercises/LockWorkshop.java | 12 ++++--- .../exercises/SynchronizedWorkshop.java | 9 ++--- .../java/workshop/exercises/TaylorSeries.java | 33 +++++++++++++++---- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java b/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java index 91ba6a8..f872f2d 100644 --- a/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java +++ b/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java @@ -20,18 +20,19 @@ public class DeadlockPreventionWorkshop { } public static void useResources(Resource r1, Resource r2) { - // TODO: Prevent deadlock by enforcing a consistent lock acquisition order - // Hint: Compare resource IDs and always synchronize on the resource with the smaller ID first. - - System.out.println(Thread.currentThread().getName() + " is attempting to lock " + r1.getName()); - synchronized (r1) { - System.out.println("+ " + Thread.currentThread().getName() + " locked " + r1.getName()); + // تشخیص اینکه کدام منبع ID کوچکتر و کدام بزرگتر دارد + Resource firstLock = r1.getId() < r2.getId() ? r1 : r2; + Resource secondLock = r1.getId() < r2.getId() ? r2 : r1; + + System.out.println(Thread.currentThread().getName() + " is attempting to lock " + firstLock.getName()); + synchronized (firstLock) { + System.out.println(" " + Thread.currentThread().getName() + " locked " + firstLock.getName()); try { Thread.sleep(100); } catch (InterruptedException ignored) {} - - System.out.println(Thread.currentThread().getName() + " is attempting to lock " + r2.getName()); - synchronized (r2) { - System.out.println("+ " + Thread.currentThread().getName() + " locked " + r2.getName()); - System.out.println(Thread.currentThread().getName() + " using " + r1.getName() + " and " + r2.getName()); + + System.out.println(Thread.currentThread().getName() + " is attempting to lock " + secondLock.getName()); + synchronized (secondLock) { + System.out.println(" " + Thread.currentThread().getName() + " locked " + secondLock.getName()); + System.out.println(Thread.currentThread().getName() + " is using " + firstLock.getName() + " and " + secondLock.getName()); } } } diff --git a/src/main/java/workshop/exercises/LockWorkshop.java b/src/main/java/workshop/exercises/LockWorkshop.java index ec24ecf..1082e1f 100644 --- a/src/main/java/workshop/exercises/LockWorkshop.java +++ b/src/main/java/workshop/exercises/LockWorkshop.java @@ -5,16 +5,20 @@ import java.util.concurrent.locks.ReentrantLock; public class LockWorkshop { public static int counter = 0; - - // TODO: Create a ReentrantLock instance to protect the critical section + + private static final java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock(); public static class MyRunnable implements Runnable { @Override public void run() { int i; for (i = 0; i < 1_000_000; i++) { - // TODO: Acquire the lock, increment the counter, and release the lock safely in a finally block - counter += 1; + lock.lock(); + try { + counter += 1; + } finally { + lock.unlock(); + } } System.out.println("Increments completed by " + Thread.currentThread().getName() + ": " + i); } diff --git a/src/main/java/workshop/exercises/SynchronizedWorkshop.java b/src/main/java/workshop/exercises/SynchronizedWorkshop.java index 9259d8e..7e8f2b1 100644 --- a/src/main/java/workshop/exercises/SynchronizedWorkshop.java +++ b/src/main/java/workshop/exercises/SynchronizedWorkshop.java @@ -2,16 +2,17 @@ package workshop.exercises; public class SynchronizedWorkshop { public static int counter = 0; - - // TODO: Define a lock object to prevent race condition + + private static final Object lockObject = new Object(); public static class MyRunnable implements Runnable { @Override public void run() { int i; for (i = 0; i < 1_000_000; i++) { - // TODO: Use a synchronized block to protect the counter increment - counter += 1; + synchronized (lockObject) { + counter += 1; + } } System.out.println("Increments completed by " + Thread.currentThread().getName() + ": " + i); } diff --git a/src/main/java/workshop/exercises/TaylorSeries.java b/src/main/java/workshop/exercises/TaylorSeries.java index d63a18e..b6960da 100644 --- a/src/main/java/workshop/exercises/TaylorSeries.java +++ b/src/main/java/workshop/exercises/TaylorSeries.java @@ -8,7 +8,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class TaylorSeries { - + public static class CalculateSin implements Runnable { private final MathContext mc = new MathContext(1000); private final BigDecimal x; @@ -21,14 +21,32 @@ public class TaylorSeries { @Override public void run() { - // TODO: Calculate the n-th term of the Taylor series for sin(x): - // term = (-1)^n * (x^(2n+1)) / (2n+1)! - // Add the term to the global sum ensuring thread-safety. + // ۱. محاسبه صورت کسر: (-1)^n * x^(2n+1) + int exponent = 2 * n + 1; + BigDecimal numerator = x.pow(exponent, mc); + if (n % 2 != 0) { + numerator = numerator.negate(); + } + + // ۲. محاسبه مخرج کسر: (2n+1)! + BigDecimal denominator = factorial(exponent); + + // ۳. تقسیم صورت بر مخرج + BigDecimal term = numerator.divide(denominator, mc); + + // ۴. جمع زدن ایمن با متغیر جهانی sum + synchronized (TaylorSeries.class) { + sum = sum.add(term, mc); + } } - // TODO: Implement factorial(k) using BigDecimal + // پیاده‌سازی متد فاکتوریل private BigDecimal factorial(int k) { - return BigDecimal.ZERO; + BigDecimal result = BigDecimal.ONE; + for (int i = 2; i <= k; i++) { + result = result.multiply(new BigDecimal(i), mc); + } + return result; } } @@ -41,7 +59,8 @@ public class TaylorSeries { // Submit tasks to calculate terms for (int i = 0; i < 100; i++) { - // TODO: Submit task to the thread pool + // جایگذاری TODO سوم: ارسال تسک به ترد پول + threadPool.submit(new CalculateSin(x, i)); } threadPool.shutdown();