From 4712166086692badf6cd92285fcdced3e850fdb4 Mon Sep 17 00:00:00 2001 From: Arefe Talebi Date: Fri, 26 Jun 2026 23:16:19 +0330 Subject: [PATCH] WS08' --- .../exercises/DeadlockPreventionWorkshop.java | 9 +- .../java/workshop/exercises/LockWorkshop.java | 43 ++++--- .../exercises/SynchronizedWorkshop.java | 39 ++++--- .../java/workshop/exercises/TaylorSeries.java | 105 ++++++++++-------- 4 files changed, 113 insertions(+), 83 deletions(-) diff --git a/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java b/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java index 91ba6a8..acbd3f4 100644 --- a/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java +++ b/src/main/java/workshop/exercises/DeadlockPreventionWorkshop.java @@ -21,7 +21,14 @@ 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. + Resource first = r1; + Resource second = r2; + if (r1.getId() > r2.getId()) { + first = r2; + second = r1; + } + r1 = first; + r2 = second; System.out.println(Thread.currentThread().getName() + " is attempting to lock " + r1.getName()); synchronized (r1) { diff --git a/src/main/java/workshop/exercises/LockWorkshop.java b/src/main/java/workshop/exercises/LockWorkshop.java index ec24ecf..f491632 100644 --- a/src/main/java/workshop/exercises/LockWorkshop.java +++ b/src/main/java/workshop/exercises/LockWorkshop.java @@ -5,8 +5,9 @@ import java.util.concurrent.locks.ReentrantLock; public class LockWorkshop { public static int counter = 0; - + // TODO: Create a ReentrantLock instance to protect the critical section + public static final Lock lock = new ReentrantLock(); public static class MyRunnable implements Runnable { @Override @@ -14,24 +15,30 @@ public class LockWorkshop { 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); } - System.out.println("Increments completed by " + Thread.currentThread().getName() + ": " + i); + } + + public static void main(String[] args) throws InterruptedException { + counter = 0; + + Thread thread1 = new Thread(new MyRunnable(), "Thread-1"); + Thread thread2 = new Thread(new MyRunnable(), "Thread-2"); + + thread1.start(); + thread2.start(); + + thread1.join(); + thread2.join(); + + System.out.println("Final counter value (expected 2000000): " + counter); } } - - public static void main(String[] args) throws InterruptedException { - counter = 0; - - Thread thread1 = new Thread(new MyRunnable(), "Thread-1"); - Thread thread2 = new Thread(new MyRunnable(), "Thread-2"); - - thread1.start(); - thread2.start(); - - thread1.join(); - thread2.join(); - - System.out.println("Final counter value (expected 2000000): " + counter); - } } diff --git a/src/main/java/workshop/exercises/SynchronizedWorkshop.java b/src/main/java/workshop/exercises/SynchronizedWorkshop.java index 9259d8e..1b7f3a2 100644 --- a/src/main/java/workshop/exercises/SynchronizedWorkshop.java +++ b/src/main/java/workshop/exercises/SynchronizedWorkshop.java @@ -2,8 +2,9 @@ package workshop.exercises; public class SynchronizedWorkshop { public static int counter = 0; - + // TODO: Define a lock object to prevent race condition + public static final Object lock = new Object(); public static class MyRunnable implements Runnable { @Override @@ -11,24 +12,26 @@ public class SynchronizedWorkshop { int i; for (i = 0; i < 1_000_000; i++) { // TODO: Use a synchronized block to protect the counter increment - counter += 1; + synchronized (lock) { + counter += 1; + } + System.out.println("Increments completed by " + Thread.currentThread().getName() + ": " + i); } - System.out.println("Increments completed by " + Thread.currentThread().getName() + ": " + i); + } + + public static void main(String[] args) throws InterruptedException { + counter = 0; + + Thread thread1 = new Thread(new MyRunnable(), "Thread-1"); + Thread thread2 = new Thread(new MyRunnable(), "Thread-2"); + + thread1.start(); + thread2.start(); + + thread1.join(); + thread2.join(); + + System.out.println("Final counter value (expected 2000000): " + counter); } } - - public static void main(String[] args) throws InterruptedException { - counter = 0; - - Thread thread1 = new Thread(new MyRunnable(), "Thread-1"); - Thread thread2 = new Thread(new MyRunnable(), "Thread-2"); - - thread1.start(); - thread2.start(); - - thread1.join(); - thread2.join(); - - System.out.println("Final counter value (expected 2000000): " + counter); - } } diff --git a/src/main/java/workshop/exercises/TaylorSeries.java b/src/main/java/workshop/exercises/TaylorSeries.java index d63a18e..8fd54d0 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; @@ -22,54 +22,67 @@ 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. + BigDecimal numerator = x.pow(2 * n + 1, mc); + BigDecimal denominator = factorial(2 * n + 1); + + BigDecimal term = numerator.divide(denominator, mc); + + if (n % 2 != 0) { + term = term.negate(); + } + + synchronized (TaylorSeries.class) { + sum = sum.add(term, mc); + } } - - // TODO: Implement factorial(k) using BigDecimal - private BigDecimal factorial(int k) { - return BigDecimal.ZERO; + // TODO: Implement factorial(k) using BigDecimal + private BigDecimal factorial(int k) { + BigDecimal result = BigDecimal.ONE; + for (int i = 2; i <= k; i++) { + result = result.multiply(BigDecimal.valueOf(i)); + } + return result; + } } - } + public static BigDecimal sum = BigDecimal.ZERO; - public static BigDecimal sum = BigDecimal.ZERO; + public static void main (String[]args){ + ExecutorService threadPool = Executors.newFixedThreadPool(4); + sum = BigDecimal.ZERO; + BigDecimal x = new BigDecimal("0.01"); - public static void main(String[] args) { - ExecutorService threadPool = Executors.newFixedThreadPool(4); - sum = BigDecimal.ZERO; - BigDecimal x = new BigDecimal("0.01"); + // Submit tasks to calculate terms + for (int i = 0; i < 100; i++) { + // TODO: Submit task to the thread pool + threadPool.submit(new CalculateSin(x, i)); + } - // Submit tasks to calculate terms - for (int i = 0; i < 100; i++) { - // TODO: Submit task to the thread pool + threadPool.shutdown(); + try { + threadPool.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + // Pre-calculated accurate value of sin(0.01) up to 1000 decimal places + BigDecimal accurateValue = new BigDecimal("0.009999833334166664682542438269099729038964385360169151033879" + + "1124794097345090639159659426367929614989901525182568937606738071143914781018343679925045223748779233" + + "4633395662957704288475175228160558357110105077439518716860615533070998720636987509269668842490541364" + + "2046237535076816415219593915753970609625155007149734343650140126010756472960507873872984042987441343" + + "4632784947709943715670321717675280271359744354619523360203501121465199963741173489051927920551271878" + + "0890799396861427770050764919858890678677220571952090318596147460309593993397336341626522171452145068" + + "2733933417711179372733354590095099959888961964291389175600643442999116373725594047366187408263088683" + + "4976343405988894064532908768068263525544004211332459809773301487980907370431155859574851192235000645" + + "6064003773432638837702651724406011257895842835907410397326351149391214249645075873929695397792073094" + + "1188402364506858174852606021099282767046225114299907364917050686481947141812831031312882254660611456" + + "524573907422800164140884130285721050703575"); + + sum = sum.setScale(1000, RoundingMode.HALF_DOWN); + accurateValue = accurateValue.setScale(1000, RoundingMode.HALF_DOWN); + + System.out.println("sin(0.01) up to 1000 decimal places:"); + System.out.println("Calculated Value: " + sum.toPlainString()); + System.out.println("Accurate Value: " + accurateValue.toPlainString()); + System.out.println("Difference: " + accurateValue.subtract(sum).abs().toPlainString()); + } } - - threadPool.shutdown(); - try { - threadPool.awaitTermination(10, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - // Pre-calculated accurate value of sin(0.01) up to 1000 decimal places - BigDecimal accurateValue = new BigDecimal("0.009999833334166664682542438269099729038964385360169151033879" + - "1124794097345090639159659426367929614989901525182568937606738071143914781018343679925045223748779233" + - "4633395662957704288475175228160558357110105077439518716860615533070998720636987509269668842490541364" + - "2046237535076816415219593915753970609625155007149734343650140126010756472960507873872984042987441343" + - "4632784947709943715670321717675280271359744354619523360203501121465199963741173489051927920551271878" + - "0890799396861427770050764919858890678677220571952090318596147460309593993397336341626522171452145068" + - "2733933417711179372733354590095099959888961964291389175600643442999116373725594047366187408263088683" + - "4976343405988894064532908768068263525544004211332459809773301487980907370431155859574851192235000645" + - "6064003773432638837702651724406011257895842835907410397326351149391214249645075873929695397792073094" + - "1188402364506858174852606021099282767046225114299907364917050686481947141812831031312882254660611456" + - "524573907422800164140884130285721050703575"); - - sum = sum.setScale(1000, RoundingMode.HALF_DOWN); - accurateValue = accurateValue.setScale(1000, RoundingMode.HALF_DOWN); - - System.out.println("sin(0.01) up to 1000 decimal places:"); - System.out.println("Calculated Value: " + sum.toPlainString()); - System.out.println("Accurate Value: " + accurateValue.toPlainString()); - System.out.println("Difference: " + accurateValue.subtract(sum).abs().toPlainString()); - } -}