From bc9b7eef2d22987c35f4514fb7c9d8bc016cbacf Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 16:09:26 +0000 Subject: [PATCH 1/7] add deadline --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7a6ba3..e974d43 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/qcWcnElX) # Java concurrency # Цели и задачи л/р: From f6cd21069465a204a2dccb89faf4612927a06aff Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Tue, 4 Nov 2025 19:20:01 +0300 Subject: [PATCH 2/7] added solution --- .idea/.gitignore | 3 + .idea/.name | 1 + .idea/gradle.xml | 16 +++++ .idea/misc.xml | 5 ++ .idea/vcs.xml | 6 ++ src/main/java/org/labs/Main.java | 27 ++++++++- src/main/java/org/labs/Programmer.java | 72 +++++++++++++++++++++++ src/main/java/org/labs/SpoonManager.java | 37 ++++++++++++ src/main/java/org/labs/TimeUtil.java | 15 +++++ src/main/java/org/labs/Waiter.java | 38 ++++++++++++ src/main/java/org/labs/WaiterService.java | 51 ++++++++++++++++ src/main/java/org/labs/WaiterTask.java | 34 +++++++++++ 12 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 src/main/java/org/labs/Programmer.java create mode 100644 src/main/java/org/labs/SpoonManager.java create mode 100644 src/main/java/org/labs/TimeUtil.java create mode 100644 src/main/java/org/labs/Waiter.java create mode 100644 src/main/java/org/labs/WaiterService.java create mode 100644 src/main/java/org/labs/WaiterTask.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..a0a9a28 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +parallel-lab11 \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..ce1c62c --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..03872dd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index 9917247..b770849 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -1,7 +1,28 @@ package org.labs; public class Main { - public static void main(String[] args) { - System.out.println("Hello, World!"); + + public static void main(String[] args) throws InterruptedException { + startDinner(30, 20, 10000); + System.out.println(Runtime.getRuntime().availableProcessors()); + } + + public static void startDinner(int progsCount, int waitersCount, int portions) throws InterruptedException { + SpoonManager spoonManager = new SpoonManager(progsCount); + Programmer[] programmers = new Programmer[progsCount]; + WaiterService waiterService = new WaiterService(waitersCount, portions); + for (int i = 0; i < progsCount; i++) { + programmers[i] = new Programmer(i, spoonManager, waiterService); + } + for (int i = 0; i < progsCount; i++) { + programmers[i].start(); + } + + for (int i = 0; i < progsCount; i++) { + programmers[i].join(); + } + + waiterService.shutdown(); } -} \ No newline at end of file +} + diff --git a/src/main/java/org/labs/Programmer.java b/src/main/java/org/labs/Programmer.java new file mode 100644 index 0000000..229ceb2 --- /dev/null +++ b/src/main/java/org/labs/Programmer.java @@ -0,0 +1,72 @@ +package org.labs; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class Programmer extends Thread { + + private final int id; + private final SpoonManager spoonManager; + private final WaiterService waiterService; + + private boolean hasPortion; + private int eaten = 0; + + public Programmer(int id, SpoonManager manager, WaiterService waiterService) { + this.id = id; + this.spoonManager = manager; + this.waiterService = waiterService; + this.hasPortion = true; + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + code(); + + if (!hasPortion) { + break; + } + + spoonManager.aquireSpoons(id); + try { + eat(); + } finally { + spoonManager.releaseSpoons(id); + } + try { + CompletableFuture getFoodFuture = waiterService.requestFood(eaten); + hasPortion = getFoodFuture.get(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } catch (ExecutionException e) { + System.err.println("Waiter failed to bring new portion: " + e.getCause()); + break; + } catch (TimeoutException e) { + System.err.println("No response from waiter"); + break; + } + } + System.out.println("Programmer-" + id + " has eaten " + eaten + " portions"); + } + + private void eat() { + try { + Thread.sleep(TimeUtil.randomTime(TimeUtil.MIN_WAIT_TIME, TimeUtil.MAX_WAIT_TIME)); + eaten++; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void code() { + try { + Thread.sleep(TimeUtil.randomTime(TimeUtil.MIN_WAIT_TIME, TimeUtil.MAX_WAIT_TIME)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} diff --git a/src/main/java/org/labs/SpoonManager.java b/src/main/java/org/labs/SpoonManager.java new file mode 100644 index 0000000..50b2ee4 --- /dev/null +++ b/src/main/java/org/labs/SpoonManager.java @@ -0,0 +1,37 @@ +package org.labs; + +import java.util.concurrent.locks.ReentrantLock; + +public class SpoonManager { + private final int resourceCount; + private final ReentrantLock[] issued; + + public SpoonManager(int resourceCount) { + this.resourceCount = resourceCount; + this.issued = new ReentrantLock[resourceCount]; + for (int i = 0; i < resourceCount; i++) { + issued[i] = new ReentrantLock(); + } + } + + public void aquireSpoons(int programmerId) { + int leftSpoonIdx = leftSpoonIdx(programmerId); + int rightSpoonIdx = rightSpoonIdx(programmerId); + + issued[Math.min(leftSpoonIdx, rightSpoonIdx)].lock(); + issued[Math.max(leftSpoonIdx, rightSpoonIdx)].lock(); + } + + public void releaseSpoons(int programmerId) { + issued[leftSpoonIdx(programmerId)].unlock(); + issued[rightSpoonIdx(programmerId)].unlock(); + } + + private int rightSpoonIdx(int programmerId) { + return programmerId; + } + + private int leftSpoonIdx(int programmerId) { + return (programmerId + 1) % resourceCount; + } +} diff --git a/src/main/java/org/labs/TimeUtil.java b/src/main/java/org/labs/TimeUtil.java new file mode 100644 index 0000000..9fd30c1 --- /dev/null +++ b/src/main/java/org/labs/TimeUtil.java @@ -0,0 +1,15 @@ +package org.labs; + +public class TimeUtil { + + public static Integer MIN_WAIT_TIME = 1; + public static Integer MAX_WAIT_TIME = 3; + + public static long randomTime(int min, int max) { + return min + (long)(Math.random() * (max - min)); + } + + private TimeUtil() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/org/labs/Waiter.java b/src/main/java/org/labs/Waiter.java new file mode 100644 index 0000000..abc99fa --- /dev/null +++ b/src/main/java/org/labs/Waiter.java @@ -0,0 +1,38 @@ +package org.labs; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +public class Waiter extends Thread { + + private final int id; + private final BlockingQueue taskQueue; + private boolean running; + + public Waiter(int id, BlockingQueue taskQueue) { + this.running = true; + this.id = id; + this.taskQueue = taskQueue; + } + + @Override + public void run() { + while (running && !Thread.currentThread().isInterrupted()) { + try { + WaiterTask task = taskQueue.poll(1, TimeUnit.SECONDS); + if (task != null) { + task.call(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } + System.out.printf("Waiter-%d is shutting down%n", id); + } + + public void stopWorking() { + this.running = false; + this.interrupt(); + } +} diff --git a/src/main/java/org/labs/WaiterService.java b/src/main/java/org/labs/WaiterService.java new file mode 100644 index 0000000..249ccf6 --- /dev/null +++ b/src/main/java/org/labs/WaiterService.java @@ -0,0 +1,51 @@ +package org.labs; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Сервис для обслуживания программистов + */ +public class WaiterService { + private final AtomicInteger portions; + private final PriorityBlockingQueue blockingQueue; + private final Waiter[] waiters; + + public WaiterService(int waitersCount, int portionCount) { + blockingQueue = new PriorityBlockingQueue<>(); + portions = new AtomicInteger(portionCount); + waiters = new Waiter[waitersCount]; + for (int i = 0; i < waitersCount; i++) { + waiters[i] = new Waiter(i, blockingQueue); + } + + startWaiters(); + } + + public CompletableFuture requestFood(int eatenBefore) throws InterruptedException { + CompletableFuture future = new CompletableFuture<>(); + blockingQueue.offer(new WaiterTask(eatenBefore, portions, future)); + return future; + } + + private void startWaiters() { + for (Waiter waiter : waiters) { + waiter.start(); + } + } + + public void shutdown() { + for (Waiter waiter : waiters) { + waiter.stopWorking(); + } + + for (Waiter waiter : waiters) { + try { + waiter.join(3000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/src/main/java/org/labs/WaiterTask.java b/src/main/java/org/labs/WaiterTask.java new file mode 100644 index 0000000..d838409 --- /dev/null +++ b/src/main/java/org/labs/WaiterTask.java @@ -0,0 +1,34 @@ +package org.labs; + +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; + +public class WaiterTask implements Callable, Comparable { + private final int eatenBefore; + private final AtomicInteger portions; + private final CompletableFuture resultFuture; + + public WaiterTask(int eatenBefore, AtomicInteger portions, CompletableFuture resultFuture) { + this.eatenBefore = eatenBefore; + this.portions = portions; + this.resultFuture = resultFuture; + } + + @Override + public Boolean call() { + try { + Thread.sleep(TimeUtil.randomTime(TimeUtil.MIN_WAIT_TIME, TimeUtil.MAX_WAIT_TIME)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + boolean result = portions.getAndDecrement() > 0; + resultFuture.complete(result); + return result; + } + + @Override + public int compareTo(WaiterTask o) { + return Integer.compare(this.eatenBefore, o.eatenBefore); + } +} From b64c04c99b3a735940e00818a8dd5a49e64318ef Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Tue, 4 Nov 2025 21:37:53 +0300 Subject: [PATCH 3/7] Added tests + refactoring --- gradlew | 0 src/main/java/org/labs/Main.java | 8 ++--- src/main/java/org/labs/Programmer.java | 36 +++++++++++++-------- src/main/java/org/labs/TimeUtil.java | 5 ++- src/main/java/org/labs/Waiter.java | 5 +-- src/main/java/org/labs/WaiterTask.java | 8 +++++ src/test/java/org/labs/FairnessTest.java | 37 ++++++++++++++++++++++ src/test/java/org/labs/ProgrammerTest.java | 36 +++++++++++++++++++++ src/test/java/org/labs/WaiterTest.java | 30 ++++++++++++++++++ 9 files changed, 140 insertions(+), 25 deletions(-) mode change 100644 => 100755 gradlew create mode 100644 src/test/java/org/labs/FairnessTest.java create mode 100644 src/test/java/org/labs/ProgrammerTest.java create mode 100644 src/test/java/org/labs/WaiterTest.java diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index b770849..c59ed87 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -3,8 +3,7 @@ public class Main { public static void main(String[] args) throws InterruptedException { - startDinner(30, 20, 10000); - System.out.println(Runtime.getRuntime().availableProcessors()); + startDinner(7, 2, 100000); } public static void startDinner(int progsCount, int waitersCount, int portions) throws InterruptedException { @@ -13,16 +12,17 @@ public static void startDinner(int progsCount, int waitersCount, int portions) t WaiterService waiterService = new WaiterService(waitersCount, portions); for (int i = 0; i < progsCount; i++) { programmers[i] = new Programmer(i, spoonManager, waiterService); - } - for (int i = 0; i < progsCount; i++) { programmers[i].start(); } + int total = 0; for (int i = 0; i < progsCount; i++) { programmers[i].join(); + total += programmers[i].getEaten(); } waiterService.shutdown(); + System.out.println("TOTAL EATEN " + total); } } diff --git a/src/main/java/org/labs/Programmer.java b/src/main/java/org/labs/Programmer.java index 229ceb2..9bb07f6 100644 --- a/src/main/java/org/labs/Programmer.java +++ b/src/main/java/org/labs/Programmer.java @@ -18,7 +18,7 @@ public Programmer(int id, SpoonManager manager, WaiterService waiterService) { this.id = id; this.spoonManager = manager; this.waiterService = waiterService; - this.hasPortion = true; + this.hasPortion = false; } @Override @@ -26,6 +26,7 @@ public void run() { while (!Thread.currentThread().isInterrupted()) { code(); + hasPortion = requestFoodWithTimeout(eaten); if (!hasPortion) { break; } @@ -36,23 +37,30 @@ public void run() { } finally { spoonManager.releaseSpoons(id); } - try { - CompletableFuture getFoodFuture = waiterService.requestFood(eaten); - hasPortion = getFoodFuture.get(5, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } catch (ExecutionException e) { - System.err.println("Waiter failed to bring new portion: " + e.getCause()); - break; - } catch (TimeoutException e) { - System.err.println("No response from waiter"); - break; - } } System.out.println("Programmer-" + id + " has eaten " + eaten + " portions"); } + public int getEaten() { + return eaten; + } + + private boolean requestFoodWithTimeout(int eaten) { + try { + CompletableFuture getFoodFuture = waiterService.requestFood(eaten); + return getFoodFuture.get(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } catch (ExecutionException e) { + System.err.println("Waiter failed to bring new portion: " + e.getCause()); + return false; + } catch (TimeoutException e) { + System.err.println("No response from waiter"); + return false; + } + } + private void eat() { try { Thread.sleep(TimeUtil.randomTime(TimeUtil.MIN_WAIT_TIME, TimeUtil.MAX_WAIT_TIME)); diff --git a/src/main/java/org/labs/TimeUtil.java b/src/main/java/org/labs/TimeUtil.java index 9fd30c1..34b2f08 100644 --- a/src/main/java/org/labs/TimeUtil.java +++ b/src/main/java/org/labs/TimeUtil.java @@ -1,9 +1,8 @@ package org.labs; public class TimeUtil { - - public static Integer MIN_WAIT_TIME = 1; - public static Integer MAX_WAIT_TIME = 3; + public static final Integer MIN_WAIT_TIME = 1; + public static final Integer MAX_WAIT_TIME = 3; public static long randomTime(int min, int max) { return min + (long)(Math.random() * (max - min)); diff --git a/src/main/java/org/labs/Waiter.java b/src/main/java/org/labs/Waiter.java index abc99fa..0a68d99 100644 --- a/src/main/java/org/labs/Waiter.java +++ b/src/main/java/org/labs/Waiter.java @@ -7,17 +7,15 @@ public class Waiter extends Thread { private final int id; private final BlockingQueue taskQueue; - private boolean running; public Waiter(int id, BlockingQueue taskQueue) { - this.running = true; this.id = id; this.taskQueue = taskQueue; } @Override public void run() { - while (running && !Thread.currentThread().isInterrupted()) { + while (!Thread.currentThread().isInterrupted()) { try { WaiterTask task = taskQueue.poll(1, TimeUnit.SECONDS); if (task != null) { @@ -32,7 +30,6 @@ public void run() { } public void stopWorking() { - this.running = false; this.interrupt(); } } diff --git a/src/main/java/org/labs/WaiterTask.java b/src/main/java/org/labs/WaiterTask.java index d838409..491c369 100644 --- a/src/main/java/org/labs/WaiterTask.java +++ b/src/main/java/org/labs/WaiterTask.java @@ -22,6 +22,10 @@ public Boolean call() { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } + int remainingPortions = portions.get(); + if (remainingPortions % 5000 == 0) { + System.out.println("Portions left - " + remainingPortions); + } boolean result = portions.getAndDecrement() > 0; resultFuture.complete(result); return result; @@ -31,4 +35,8 @@ public Boolean call() { public int compareTo(WaiterTask o) { return Integer.compare(this.eatenBefore, o.eatenBefore); } + + public int getEatenBefore() { + return eatenBefore; + } } diff --git a/src/test/java/org/labs/FairnessTest.java b/src/test/java/org/labs/FairnessTest.java new file mode 100644 index 0000000..7beec40 --- /dev/null +++ b/src/test/java/org/labs/FairnessTest.java @@ -0,0 +1,37 @@ +package org.labs; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class FairnessTest { + + @Test + void testFairPortionDistribution() throws InterruptedException { + int progsCount = 7; + int waitersCount = 2; + int portions = 10000; + + SpoonManager spoonManager = new SpoonManager(progsCount); + Programmer[] programmers = new Programmer[progsCount]; + WaiterService waiterService = new WaiterService(waitersCount, portions); + for (int i = 0; i < progsCount; i++) { + programmers[i] = new Programmer(i, spoonManager, waiterService); + programmers[i].start(); + } + + for (int i = 0; i < progsCount; i++) { + programmers[i].join(20000); + } + + double possibleDeviation = 0.1; + double average = portions / (double) progsCount; + int totalEaten = 0; + for (Programmer programmer : programmers) { + assertTrue(Math.abs(average - programmer.getEaten()) / average <= possibleDeviation); + totalEaten += programmer.getEaten(); + } + waiterService.shutdown(); + + assertEquals(portions, totalEaten); + } +} diff --git a/src/test/java/org/labs/ProgrammerTest.java b/src/test/java/org/labs/ProgrammerTest.java new file mode 100644 index 0000000..900dbef --- /dev/null +++ b/src/test/java/org/labs/ProgrammerTest.java @@ -0,0 +1,36 @@ +package org.labs; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ProgrammerTest { + + @Test + void testEarlyInterruption() throws InterruptedException { + int progsCount = 7; + int waitersCount = 2; + int portions = 10000; + + SpoonManager spoonManager = new SpoonManager(progsCount); + Programmer[] programmers = new Programmer[progsCount]; + WaiterService waiterService = new WaiterService(waitersCount, portions); + for (int i = 0; i < progsCount; i++) { + programmers[i] = new Programmer(i, spoonManager, waiterService); + programmers[i].start(); + } + + Thread.sleep(1000); + + int totalEaten = 0; + for (Programmer programmer : programmers) { + programmer.interrupt(); + programmer.join(); + totalEaten += programmer.getEaten(); + } + + waiterService.shutdown(); + + assertTrue(totalEaten < portions); + } +} diff --git a/src/test/java/org/labs/WaiterTest.java b/src/test/java/org/labs/WaiterTest.java new file mode 100644 index 0000000..2ecd9cf --- /dev/null +++ b/src/test/java/org/labs/WaiterTest.java @@ -0,0 +1,30 @@ +package org.labs; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WaiterTest { + + @Test + public void testWaiterPriorityQueue() throws InterruptedException { + PriorityBlockingQueue queue = new PriorityBlockingQueue<>(); + AtomicInteger portions = new AtomicInteger(100); + + queue.offer(createTask(10, portions)); + queue.offer(createTask(5, portions)); + queue.offer(createTask(15, portions)); + + assertEquals(5, queue.take().getEatenBefore()); + assertEquals(10, queue.take().getEatenBefore()); + assertEquals(15, queue.take().getEatenBefore()); + } + + private WaiterTask createTask(int eatenBefore, AtomicInteger portions) { + return new WaiterTask(eatenBefore, portions, new CompletableFuture<>()); + } +} \ No newline at end of file From bb3e15a0d2ceedc583a2fc863a27a0c2ed473c6a Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Tue, 4 Nov 2025 21:43:46 +0300 Subject: [PATCH 4/7] fix diff --- .idea/.gitignore | 3 - .idea/.name | 1 - .idea/gradle.xml | 16 ----- .idea/misc.xml | 5 -- .idea/vcs.xml | 6 -- .idea/workspace.xml | 89 ++++++++++++++++++++++++++ README.md | 1 - src/test/java/org/labs/WaiterTest.java | 1 + 8 files changed, 90 insertions(+), 32 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/.name delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index a0a9a28..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -parallel-lab11 \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index ce1c62c..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 03872dd..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..b26a035 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + { + "associatedIndex": 3 +} + + + + { + "keyToString": { + "Gradle.java-concurrency-vbandurin7 [:org.labs.Dinner.main()].executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.git.unshallow": "true", + "git-widget-placeholder": "master", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "/Users/v.bandurin/ITMO/java-concurrency-vbandurin7" + } +} + + + + + + + + + + + + + + + + + + + + 1758472936634 + + + + \ No newline at end of file diff --git a/README.md b/README.md index e974d43..d7a6ba3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/qcWcnElX) # Java concurrency # Цели и задачи л/р: diff --git a/src/test/java/org/labs/WaiterTest.java b/src/test/java/org/labs/WaiterTest.java index 2ecd9cf..1e0ca5f 100644 --- a/src/test/java/org/labs/WaiterTest.java +++ b/src/test/java/org/labs/WaiterTest.java @@ -24,6 +24,7 @@ public void testWaiterPriorityQueue() throws InterruptedException { assertEquals(15, queue.take().getEatenBefore()); } + private WaiterTask createTask(int eatenBefore, AtomicInteger portions) { return new WaiterTask(eatenBefore, portions, new CompletableFuture<>()); } From ce16428f97d6365a593ec7dbf13842a23a062425 Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Tue, 4 Nov 2025 21:45:33 +0300 Subject: [PATCH 5/7] fix diff --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b63da45..df54656 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build/ !**/src/test/**/build/ ### IntelliJ IDEA ### +.idea/ .idea/modules.xml .idea/jarRepositories.xml .idea/compiler.xml From 873d980ff1a6d7f2b9c0a8a7b05e1f8fe1f225e3 Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Tue, 4 Nov 2025 21:46:15 +0300 Subject: [PATCH 6/7] fix diff --- .gitignore | 1 - .idea/workspace.xml | 89 --------------------------------------------- 2 files changed, 90 deletions(-) delete mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index df54656..b63da45 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ build/ !**/src/test/**/build/ ### IntelliJ IDEA ### -.idea/ .idea/modules.xml .idea/jarRepositories.xml .idea/compiler.xml diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index b26a035..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - { - "associatedIndex": 3 -} - - - - { - "keyToString": { - "Gradle.java-concurrency-vbandurin7 [:org.labs.Dinner.main()].executor": "Run", - "RunOnceActivity.ShowReadmeOnStart": "true", - "RunOnceActivity.git.unshallow": "true", - "git-widget-placeholder": "master", - "kotlin-language-version-configured": "true", - "last_opened_file_path": "/Users/v.bandurin/ITMO/java-concurrency-vbandurin7" - } -} - - - - - - - - - - - - - - - - - - - - 1758472936634 - - - - \ No newline at end of file From 90f6fe075cd4c080e714b0a11ddc0a155f184586 Mon Sep 17 00:00:00 2001 From: Vladislav Bandurin Date: Thu, 6 Nov 2025 18:24:19 +0300 Subject: [PATCH 7/7] clean code --- .idea/misc.xml | 4 + .idea/workspace.xml | 112 +++++++++++++++++++++++ src/main/java/org/labs/Main.java | 2 +- src/main/java/org/labs/SpoonManager.java | 12 +-- src/main/java/org/labs/Waiter.java | 2 +- src/main/java/org/labs/WaiterTask.java | 6 +- 6 files changed, 126 insertions(+), 12 deletions(-) create mode 100644 .idea/misc.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4944549 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..8fc3979 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/src/test/java/org/labs/FairnessTest.java + 29 + + + + + \ No newline at end of file diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index c59ed87..ba14c36 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -3,7 +3,7 @@ public class Main { public static void main(String[] args) throws InterruptedException { - startDinner(7, 2, 100000); + startDinner(7, 2, 1000); } public static void startDinner(int progsCount, int waitersCount, int portions) throws InterruptedException { diff --git a/src/main/java/org/labs/SpoonManager.java b/src/main/java/org/labs/SpoonManager.java index 50b2ee4..d40aaae 100644 --- a/src/main/java/org/labs/SpoonManager.java +++ b/src/main/java/org/labs/SpoonManager.java @@ -3,13 +3,13 @@ import java.util.concurrent.locks.ReentrantLock; public class SpoonManager { - private final int resourceCount; + private final int spoonCount; private final ReentrantLock[] issued; - public SpoonManager(int resourceCount) { - this.resourceCount = resourceCount; - this.issued = new ReentrantLock[resourceCount]; - for (int i = 0; i < resourceCount; i++) { + public SpoonManager(int spoonCount) { + this.spoonCount = spoonCount; + this.issued = new ReentrantLock[spoonCount]; + for (int i = 0; i < spoonCount; i++) { issued[i] = new ReentrantLock(); } } @@ -32,6 +32,6 @@ private int rightSpoonIdx(int programmerId) { } private int leftSpoonIdx(int programmerId) { - return (programmerId + 1) % resourceCount; + return (programmerId + 1) % spoonCount; } } diff --git a/src/main/java/org/labs/Waiter.java b/src/main/java/org/labs/Waiter.java index 0a68d99..1a3bb25 100644 --- a/src/main/java/org/labs/Waiter.java +++ b/src/main/java/org/labs/Waiter.java @@ -19,7 +19,7 @@ public void run() { try { WaiterTask task = taskQueue.poll(1, TimeUnit.SECONDS); if (task != null) { - task.call(); + task.run(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff --git a/src/main/java/org/labs/WaiterTask.java b/src/main/java/org/labs/WaiterTask.java index 491c369..59cb389 100644 --- a/src/main/java/org/labs/WaiterTask.java +++ b/src/main/java/org/labs/WaiterTask.java @@ -1,10 +1,9 @@ package org.labs; -import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; -public class WaiterTask implements Callable, Comparable { +public class WaiterTask implements Runnable, Comparable { private final int eatenBefore; private final AtomicInteger portions; private final CompletableFuture resultFuture; @@ -16,7 +15,7 @@ public WaiterTask(int eatenBefore, AtomicInteger portions, CompletableFuture 0; resultFuture.complete(result); - return result; } @Override