From eec6dc825df21e93f2139bea1967ccd7c1ec7e8b Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:27:14 +0000 Subject: [PATCH 1/9] 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 db8338a282524c39b0111e87ea65ebfdcc3be32e Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Mon, 15 Sep 2025 17:10:08 +0300 Subject: [PATCH 2/9] init commit --- build.gradle.kts | 5 +++ gradlew | 0 src/main/java/org/labs/Main.java | 21 ++++++++++++- src/main/java/org/labs/io/ParamsReader.java | 32 ++++++++++++++++++++ src/main/java/org/labs/model/Fork.java | 10 ++++++ src/main/java/org/labs/model/Programmer.java | 19 ++++++++++++ src/main/java/org/labs/model/Waiter.java | 15 +++++++++ src/main/resources/params | 3 ++ 8 files changed, 104 insertions(+), 1 deletion(-) mode change 100644 => 100755 gradlew create mode 100644 src/main/java/org/labs/io/ParamsReader.java create mode 100644 src/main/java/org/labs/model/Fork.java create mode 100644 src/main/java/org/labs/model/Programmer.java create mode 100644 src/main/java/org/labs/model/Waiter.java create mode 100644 src/main/resources/params diff --git a/build.gradle.kts b/build.gradle.kts index bda0d97..08645dd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,15 @@ plugins { id("java") + id("io.freefair.lombok") version "8.13.1" } group = "org.labs" version = "1.0-SNAPSHOT" +java { + sourceCompatibility = JavaVersion.VERSION_21 +} + repositories { mavenCentral() } 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 9917247..0a41928 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -1,7 +1,26 @@ package org.labs; +import org.labs.io.ParamsReader; +import org.labs.model.Programmer; + +import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; + public class Main { public static void main(String[] args) { - System.out.println("Hello, World!"); + var reader = new ParamsReader(); + + var params = reader.getParamsAsMap("src/main/resources/params"); + var programmersCount = params.get(PROGRAMMERS_COUNT); + + System.out.println(params.toString()); + + test(programmersCount); + } + + private static void test(int programmersCount) { + for (int i = 0; i < programmersCount; i++) { + var programmer = new Programmer(i + 1, null, null); + programmer.run(); + } } } \ No newline at end of file diff --git a/src/main/java/org/labs/io/ParamsReader.java b/src/main/java/org/labs/io/ParamsReader.java new file mode 100644 index 0000000..e834497 --- /dev/null +++ b/src/main/java/org/labs/io/ParamsReader.java @@ -0,0 +1,32 @@ +package org.labs.io; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class ParamsReader { + public static final String PROGRAMMERS_COUNT = "programmers_count"; + public static final String EAT_COUNT = "eat_count"; + public static final String WAITERS_COUNT = "waiters_count"; + + private static final Set PARAMS_NAMES = Set.of(PROGRAMMERS_COUNT, EAT_COUNT, WAITERS_COUNT); + + private static final String SEPARATOR = "="; + + public Map getParamsAsMap(String filePath) { + try (var lines = Files.lines(Paths.get(filePath))) { + return lines + .map(line -> line.split(SEPARATOR)) + .filter(val -> PARAMS_NAMES.contains(val[0])) + .collect(Collectors.toMap( + values -> values[0], + values -> Integer.parseInt(values[1]) + )); + } catch (IOException e) { + throw new RuntimeException("Can't read file " + filePath, e); + } + } +} diff --git a/src/main/java/org/labs/model/Fork.java b/src/main/java/org/labs/model/Fork.java new file mode 100644 index 0000000..8d511ba --- /dev/null +++ b/src/main/java/org/labs/model/Fork.java @@ -0,0 +1,10 @@ +package org.labs.model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class Fork { + private final int id; +} diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java new file mode 100644 index 0000000..36cabcf --- /dev/null +++ b/src/main/java/org/labs/model/Programmer.java @@ -0,0 +1,19 @@ +package org.labs.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@AllArgsConstructor +@RequiredArgsConstructor +public class Programmer implements Runnable { + private final int id; + private final Fork left; + private final Fork right; + + @Override + public void run() { + + } +} diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java new file mode 100644 index 0000000..20d15a7 --- /dev/null +++ b/src/main/java/org/labs/model/Waiter.java @@ -0,0 +1,15 @@ +package org.labs.model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class Waiter implements Runnable { + private final int id; + + @Override + public void run() { + + } +} diff --git a/src/main/resources/params b/src/main/resources/params new file mode 100644 index 0000000..4ed6f70 --- /dev/null +++ b/src/main/resources/params @@ -0,0 +1,3 @@ +programmers_count=7 +eat_count=1000000 +waiters_count=2 From f202f2d6a97e874482bc4c72c2f1ec6671bf182e Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Sat, 20 Sep 2025 13:23:52 +0300 Subject: [PATCH 3/9] non-working draft --- src/main/java/org/labs/Main.java | 35 +++++++--- src/main/java/org/labs/Simulation.java | 61 +++++++++++++++++ src/main/java/org/labs/model/Fork.java | 20 ++++-- src/main/java/org/labs/model/Programmer.java | 67 +++++++++++++++++-- src/main/java/org/labs/model/Waiter.java | 20 +++++- .../java/org/labs/service/FoodService.java | 55 +++++++++++++++ .../java/org/labs/service/QueueService.java | 40 +++++++++++ .../java/org/labs/service/WaiterService.java | 15 +++++ src/main/resources/params | 4 +- 9 files changed, 293 insertions(+), 24 deletions(-) create mode 100644 src/main/java/org/labs/Simulation.java create mode 100644 src/main/java/org/labs/service/FoodService.java create mode 100644 src/main/java/org/labs/service/QueueService.java create mode 100644 src/main/java/org/labs/service/WaiterService.java diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index 0a41928..956d64e 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -1,26 +1,43 @@ package org.labs; import org.labs.io.ParamsReader; -import org.labs.model.Programmer; +import org.labs.service.FoodService; +import org.labs.service.QueueService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.labs.io.ParamsReader.EAT_COUNT; import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; +import static org.labs.io.ParamsReader.WAITERS_COUNT; public class Main { public static void main(String[] args) { var reader = new ParamsReader(); var params = reader.getParamsAsMap("src/main/resources/params"); - var programmersCount = params.get(PROGRAMMERS_COUNT); + var eatCount = params.get(EAT_COUNT); - System.out.println(params.toString()); + var queueService = new QueueService(); + var foodService = new FoodService(eatCount); - test(programmersCount); - } + var waiters = Executors.newFixedThreadPool(params.get(WAITERS_COUNT)); + var programmers = Executors.newFixedThreadPool(params.get(PROGRAMMERS_COUNT)); - private static void test(int programmersCount) { - for (int i = 0; i < programmersCount; i++) { - var programmer = new Programmer(i + 1, null, null); - programmer.run(); + var simulation = new Simulation(params, queueService, foodService); + simulation.run(waiters, programmers); + + waiters.shutdown(); + programmers.shutdown(); + try { + waiters.awaitTermination(60, TimeUnit.SECONDS); + programmers.awaitTermination(60, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } + + System.out.println("Симуляция завершена. Сколько поел каждый:"); + foodService.getProgrammerIdToSoupCount().forEach((id, count) -> + System.out.println("Программист " + id + " поел " + count + " раз")); } } \ No newline at end of file diff --git a/src/main/java/org/labs/Simulation.java b/src/main/java/org/labs/Simulation.java new file mode 100644 index 0000000..30edcb3 --- /dev/null +++ b/src/main/java/org/labs/Simulation.java @@ -0,0 +1,61 @@ +package org.labs; + +import org.labs.model.Fork; +import org.labs.model.Programmer; +import org.labs.model.Waiter; +import org.labs.service.FoodService; +import org.labs.service.QueueService; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.locks.ReentrantLock; + +import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; +import static org.labs.io.ParamsReader.WAITERS_COUNT; + +public class Simulation { + private final Map params; + private final QueueService queueService; + private final FoodService foodService; + + private final List forks; + + public Simulation(Map params, QueueService queueService, FoodService foodService) { + this.params = params; + this.queueService = queueService; + this.foodService = foodService; + this.forks = new ArrayList<>(); + } + + public void run(ExecutorService waiters, ExecutorService programmers) { + System.out.println("Начали симуляцию"); + foodService.initSoups(params.get(PROGRAMMERS_COUNT)); + fillForks(params.get(PROGRAMMERS_COUNT)); + fillProgrammers(params.get(PROGRAMMERS_COUNT), programmers); + createWaiters(params.get(WAITERS_COUNT), waiters); + } + + private void fillForks(int forksCount) { + for (int i = 0; i < forksCount; i++) { + forks.add(new Fork(i + 1, new ReentrantLock())); + } + } + + private void fillProgrammers(int programmersCount, ExecutorService executor) { + for (int i = 0; i < programmersCount; i++) { + var programmer = new Programmer(i + 1, foodService, queueService); + programmer.setState(Programmer.State.HUNGRY); + programmer.setLeft(forks.get(i)); + programmer.setRight(forks.get((i + 1) % programmersCount)); + executor.submit(programmer); + } + } + + private void createWaiters(int waitersCount, ExecutorService executor) { + for (int i = 0; i < waitersCount; i++) { + executor.submit(new Waiter(i + 1, queueService, foodService)); + } + } +} diff --git a/src/main/java/org/labs/model/Fork.java b/src/main/java/org/labs/model/Fork.java index 8d511ba..185d1ff 100644 --- a/src/main/java/org/labs/model/Fork.java +++ b/src/main/java/org/labs/model/Fork.java @@ -1,10 +1,18 @@ package org.labs.model; -import lombok.Getter; -import lombok.RequiredArgsConstructor; +import java.util.concurrent.locks.Lock; -@Getter -@RequiredArgsConstructor -public class Fork { - private final int id; +public record Fork( + int id, + Lock lock +) { + public void pickUp(int programmerId) { + lock.lock(); + System.out.println("Программист " + programmerId + " взял вилку с id " + id); + } + + public void pickDown(int programmerId) { + lock.unlock(); + System.out.println("Программист " + programmerId + " положил вилку с id " + id); + } } diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java index 36cabcf..8b37e85 100644 --- a/src/main/java/org/labs/model/Programmer.java +++ b/src/main/java/org/labs/model/Programmer.java @@ -1,19 +1,78 @@ package org.labs.model; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.SneakyThrows; +import org.labs.service.FoodService; +import org.labs.service.QueueService; + +import java.util.concurrent.atomic.AtomicInteger; @Getter -@AllArgsConstructor @RequiredArgsConstructor public class Programmer implements Runnable { private final int id; - private final Fork left; - private final Fork right; + @Setter + private State state; + @Setter + private Fork left; + @Setter + private Fork right; + + private AtomicInteger ateSoups = new AtomicInteger(0); + + private final FoodService foodService; + private final QueueService queueService; @Override + @SneakyThrows public void run() { + while (foodService.getEatCount().get() > 0) { + try { + this.state = State.HUNGRY; + + if (!foodService.hasSoup(id)) { + System.out.println("Нет супа, программист с id = " + id + " не может поесть. Он будет ждать, когда пополнится порция"); + if (!queueService.contains(id)) { + queueService.put(id); + } + Thread.sleep(500); + // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон + } + + left.pickUp(id); + right.pickUp(id); + this.state = State.EATING; + System.out.println("Программист " + id + " начал кушать суп"); + // если суп все же есть + // то взять обе ложки, перейти в статус EATING, уменьшить значение еды, отпустить обе ложки + } finally { + right.pickDown(id); + left.pickDown(id); + System.out.println("Программист " + id + " положил вилки"); + } + + foodService.disableSoup(id); + ateSoups.incrementAndGet(); + System.out.println("Программист " + id + " начал разговаривать"); + this.state = State.TALKING; + Thread.sleep(500); + + System.out.println("Осталось еды - " + foodService.getEatCount()); + } + + foodService.addCount(id, ateSoups.get()); + // он должен думать + // посмотреть, есть ли у него суп + // если нет - попросить официанта налить и продолжить думать + // если есть - взять ложку раз, взять ложку два, начать есть суп (если все съел - отпустить ложки и начать думать) + } + public enum State { + TALKING, + EATING, + HUNGRY + ; } } diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java index 20d15a7..d6ca011 100644 --- a/src/main/java/org/labs/model/Waiter.java +++ b/src/main/java/org/labs/model/Waiter.java @@ -1,15 +1,29 @@ package org.labs.model; -import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.labs.service.FoodService; +import org.labs.service.QueueService; -@Getter @RequiredArgsConstructor public class Waiter implements Runnable { private final int id; + private final QueueService queueService; + private final FoodService foodService; @Override + @SneakyThrows public void run() { - + while (foodService.getEatCount().get() > 0) { + System.out.println("Официант " + id + ", его очередь = "); + queueService.print(); + var programmerId = queueService.take(); + System.out.println("Официант " + id + " взял программиста с id = " + programmerId); + if (programmerId != null) { + foodService.addSoupToProgrammer(programmerId); + System.out.println("Официант " + id + " добавил программисту " + programmerId + " суп"); + } + Thread.sleep(1000); + } } } diff --git a/src/main/java/org/labs/service/FoodService.java b/src/main/java/org/labs/service/FoodService.java new file mode 100644 index 0000000..28796b2 --- /dev/null +++ b/src/main/java/org/labs/service/FoodService.java @@ -0,0 +1,55 @@ +package org.labs.service; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +public class FoodService { + private final AtomicInteger eatCount; + private final Map programmerIdToSoupAvailable; + private final Map programmerIdToSoupCount; + + public FoodService(int eatCount) { + this.eatCount = new AtomicInteger(eatCount); + this.programmerIdToSoupAvailable = new ConcurrentHashMap<>(); + this.programmerIdToSoupCount = new ConcurrentHashMap<>(); + } + + public AtomicInteger getEatCount() { + return eatCount; + } + + public Map getProgrammerIdToSoupCount() { + return programmerIdToSoupCount; + } + + public void addCount(int programmerId, int count) { + this.programmerIdToSoupCount.put(programmerId, count); + } + + public void decreaseAtomicInteger() { + eatCount.decrementAndGet(); + } + + public void initSoups(int programmersCount) { + for (int i = 0; i < programmersCount; i++) { + programmerIdToSoupAvailable.put(i, true); + } + } + + public boolean hasSoup(int programmerId) { + return programmerIdToSoupAvailable.get(programmerId); + } + + public void addSoupToProgrammer(int programmerId) { + programmerIdToSoupAvailable.put(programmerId, true); + eatCount.decrementAndGet(); + } + + public void disableSoup(int programmerId) { + programmerIdToSoupAvailable.put(programmerId, false); + } + + + +} diff --git a/src/main/java/org/labs/service/QueueService.java b/src/main/java/org/labs/service/QueueService.java new file mode 100644 index 0000000..f2d2613 --- /dev/null +++ b/src/main/java/org/labs/service/QueueService.java @@ -0,0 +1,40 @@ +package org.labs.service; + +import lombok.Getter; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; + +@Getter +public class QueueService { + private final ConcurrentLinkedQueue queue; + + public QueueService() { + this.queue = new ConcurrentLinkedQueue<>(); + } + + public void put(Integer programmerId) { + this.queue.add(programmerId); + } + + public Integer take() { + if (this.queue.isEmpty()) { + return null; + } + + return queue.peek(); + } + + public boolean contains(Integer programmerId) { + return this.queue.contains(programmerId); + } + + public void remove() { + this.queue.remove(); + } + + public void print() { + System.out.println(queue); + } +} diff --git a/src/main/java/org/labs/service/WaiterService.java b/src/main/java/org/labs/service/WaiterService.java new file mode 100644 index 0000000..33efea2 --- /dev/null +++ b/src/main/java/org/labs/service/WaiterService.java @@ -0,0 +1,15 @@ +package org.labs.service; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.labs.model.Waiter; + +import java.util.List; + +@Getter +@RequiredArgsConstructor +public class WaiterService { + private final List waiters; + + +} diff --git a/src/main/resources/params b/src/main/resources/params index 4ed6f70..d229cf4 100644 --- a/src/main/resources/params +++ b/src/main/resources/params @@ -1,3 +1,3 @@ -programmers_count=7 -eat_count=1000000 +programmers_count=3 +eat_count=10 waiters_count=2 From 6d987265ccc1a287597e37666d45afbcafe052f8 Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Sat, 20 Sep 2025 13:47:55 +0300 Subject: [PATCH 4/9] no deadlock, but there's problem with sync eat count --- src/main/java/org/labs/Simulation.java | 6 ++++-- src/main/java/org/labs/service/FoodService.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/labs/Simulation.java b/src/main/java/org/labs/Simulation.java index 30edcb3..1d07659 100644 --- a/src/main/java/org/labs/Simulation.java +++ b/src/main/java/org/labs/Simulation.java @@ -47,8 +47,10 @@ private void fillProgrammers(int programmersCount, ExecutorService executor) { for (int i = 0; i < programmersCount; i++) { var programmer = new Programmer(i + 1, foodService, queueService); programmer.setState(Programmer.State.HUNGRY); - programmer.setLeft(forks.get(i)); - programmer.setRight(forks.get((i + 1) % programmersCount)); + var left = forks.get(i); + var right = forks.get((i + 1) % programmersCount); + programmer.setLeft(left.id() < right.id() ? left : right); + programmer.setRight(left.id() < right.id() ? right : left); executor.submit(programmer); } } diff --git a/src/main/java/org/labs/service/FoodService.java b/src/main/java/org/labs/service/FoodService.java index 28796b2..a0058ee 100644 --- a/src/main/java/org/labs/service/FoodService.java +++ b/src/main/java/org/labs/service/FoodService.java @@ -33,7 +33,7 @@ public void decreaseAtomicInteger() { public void initSoups(int programmersCount) { for (int i = 0; i < programmersCount; i++) { - programmerIdToSoupAvailable.put(i, true); + programmerIdToSoupAvailable.put(i + 1, true); } } From 54ad97ea4ae0ec38e5532684ac4b5869da734a81 Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Sat, 20 Sep 2025 14:41:35 +0300 Subject: [PATCH 5/9] fix peek with poll in QueueService --- src/main/java/org/labs/model/Programmer.java | 4 ++-- src/main/java/org/labs/model/Waiter.java | 2 +- src/main/java/org/labs/service/QueueService.java | 2 +- src/main/resources/params | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java index 8b37e85..07512a3 100644 --- a/src/main/java/org/labs/model/Programmer.java +++ b/src/main/java/org/labs/model/Programmer.java @@ -37,7 +37,7 @@ public void run() { if (!queueService.contains(id)) { queueService.put(id); } - Thread.sleep(500); + Thread.sleep(100); // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон } @@ -57,7 +57,7 @@ public void run() { ateSoups.incrementAndGet(); System.out.println("Программист " + id + " начал разговаривать"); this.state = State.TALKING; - Thread.sleep(500); + Thread.sleep(100); System.out.println("Осталось еды - " + foodService.getEatCount()); } diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java index d6ca011..ba3d608 100644 --- a/src/main/java/org/labs/model/Waiter.java +++ b/src/main/java/org/labs/model/Waiter.java @@ -23,7 +23,7 @@ public void run() { foodService.addSoupToProgrammer(programmerId); System.out.println("Официант " + id + " добавил программисту " + programmerId + " суп"); } - Thread.sleep(1000); + Thread.sleep(100); } } } diff --git a/src/main/java/org/labs/service/QueueService.java b/src/main/java/org/labs/service/QueueService.java index f2d2613..0a2c937 100644 --- a/src/main/java/org/labs/service/QueueService.java +++ b/src/main/java/org/labs/service/QueueService.java @@ -23,7 +23,7 @@ public Integer take() { return null; } - return queue.peek(); + return queue.poll(); } public boolean contains(Integer programmerId) { diff --git a/src/main/resources/params b/src/main/resources/params index d229cf4..6dc0ce0 100644 --- a/src/main/resources/params +++ b/src/main/resources/params @@ -1,3 +1,3 @@ programmers_count=3 -eat_count=10 +eat_count=50 waiters_count=2 From afb106fda219b156b5ab08dfc4554c3d5df6c105 Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Sat, 20 Sep 2025 15:06:54 +0300 Subject: [PATCH 6/9] tiny refactor --- src/main/java/org/labs/model/Programmer.java | 32 ++++++++++--------- src/main/java/org/labs/model/Waiter.java | 2 +- .../java/org/labs/service/FoodService.java | 15 +++------ .../java/org/labs/service/QueueService.java | 4 +-- src/main/resources/params | 2 +- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java index 07512a3..7c180dd 100644 --- a/src/main/java/org/labs/model/Programmer.java +++ b/src/main/java/org/labs/model/Programmer.java @@ -29,32 +29,35 @@ public class Programmer implements Runnable { @SneakyThrows public void run() { while (foodService.getEatCount().get() > 0) { - try { - this.state = State.HUNGRY; + this.state = State.HUNGRY; - if (!foodService.hasSoup(id)) { - System.out.println("Нет супа, программист с id = " + id + " не может поесть. Он будет ждать, когда пополнится порция"); - if (!queueService.contains(id)) { - queueService.put(id); - } - Thread.sleep(100); - // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон + while (!foodService.hasSoup(id)) { + if (foodService.getEatCount().get() < 1) { + break; } + System.out.println("Нет супа, программист с id = " + id + " не может поесть. Он будет ждать, когда пополнится порция"); + if (!queueService.contains(id)) { + queueService.put(id); + } + Thread.sleep(100); + // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон + } + + try { left.pickUp(id); right.pickUp(id); this.state = State.EATING; System.out.println("Программист " + id + " начал кушать суп"); - // если суп все же есть - // то взять обе ложки, перейти в статус EATING, уменьшить значение еды, отпустить обе ложки + foodService.disableSoup(id); + ateSoups.incrementAndGet(); + // Здесь можно добавить Thread.sleep() для симуляции времени еды, если нужно } finally { right.pickDown(id); left.pickDown(id); System.out.println("Программист " + id + " положил вилки"); } - foodService.disableSoup(id); - ateSoups.incrementAndGet(); System.out.println("Программист " + id + " начал разговаривать"); this.state = State.TALKING; Thread.sleep(100); @@ -72,7 +75,6 @@ public void run() { public enum State { TALKING, EATING, - HUNGRY - ; + HUNGRY; } } diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java index ba3d608..7606e28 100644 --- a/src/main/java/org/labs/model/Waiter.java +++ b/src/main/java/org/labs/model/Waiter.java @@ -17,7 +17,7 @@ public void run() { while (foodService.getEatCount().get() > 0) { System.out.println("Официант " + id + ", его очередь = "); queueService.print(); - var programmerId = queueService.take(); + var programmerId = queueService.poll(); System.out.println("Официант " + id + " взял программиста с id = " + programmerId); if (programmerId != null) { foodService.addSoupToProgrammer(programmerId); diff --git a/src/main/java/org/labs/service/FoodService.java b/src/main/java/org/labs/service/FoodService.java index a0058ee..81e1bdd 100644 --- a/src/main/java/org/labs/service/FoodService.java +++ b/src/main/java/org/labs/service/FoodService.java @@ -27,10 +27,6 @@ public void addCount(int programmerId, int count) { this.programmerIdToSoupCount.put(programmerId, count); } - public void decreaseAtomicInteger() { - eatCount.decrementAndGet(); - } - public void initSoups(int programmersCount) { for (int i = 0; i < programmersCount; i++) { programmerIdToSoupAvailable.put(i + 1, true); @@ -41,15 +37,14 @@ public boolean hasSoup(int programmerId) { return programmerIdToSoupAvailable.get(programmerId); } - public void addSoupToProgrammer(int programmerId) { - programmerIdToSoupAvailable.put(programmerId, true); - eatCount.decrementAndGet(); + public synchronized void addSoupToProgrammer(int programmerId) { + if (eatCount.get() > 0) { + programmerIdToSoupAvailable.put(programmerId, true); + eatCount.decrementAndGet(); + } } public void disableSoup(int programmerId) { programmerIdToSoupAvailable.put(programmerId, false); } - - - } diff --git a/src/main/java/org/labs/service/QueueService.java b/src/main/java/org/labs/service/QueueService.java index 0a2c937..8bc0e7f 100644 --- a/src/main/java/org/labs/service/QueueService.java +++ b/src/main/java/org/labs/service/QueueService.java @@ -2,8 +2,6 @@ import lombok.Getter; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; @Getter @@ -18,7 +16,7 @@ public void put(Integer programmerId) { this.queue.add(programmerId); } - public Integer take() { + public Integer poll() { if (this.queue.isEmpty()) { return null; } diff --git a/src/main/resources/params b/src/main/resources/params index 6dc0ce0..95d6698 100644 --- a/src/main/resources/params +++ b/src/main/resources/params @@ -1,3 +1,3 @@ -programmers_count=3 +programmers_count=5 eat_count=50 waiters_count=2 From 60cf979018a4865e9f231c0c00fb7f47fd9e6b63 Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Mon, 22 Sep 2025 18:18:27 +0300 Subject: [PATCH 7/9] working thing --- build.gradle.kts | 4 ++ src/main/java/org/labs/Main.java | 6 +- src/main/java/org/labs/Simulation.java | 6 +- src/main/java/org/labs/model/Fork.java | 7 ++- src/main/java/org/labs/model/Programmer.java | 57 ++++++++++--------- src/main/java/org/labs/model/Waiter.java | 14 +++-- .../java/org/labs/service/FoodService.java | 46 ++++++++------- .../java/org/labs/service/QueueService.java | 14 +---- .../java/org/labs/service/WaiterService.java | 15 ----- src/main/resources/params | 6 +- 10 files changed, 91 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/org/labs/service/WaiterService.java diff --git a/build.gradle.kts b/build.gradle.kts index 08645dd..a912783 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,10 @@ repositories { } dependencies { + implementation("org.slf4j:slf4j-api:2.0.17") + implementation("ch.qos.logback:logback-classic:1.5.18") + implementation("org.projectlombok:lombok:1.18.42") + testImplementation(platform("org.junit:junit-bom:5.10.0")) testImplementation("org.junit.jupiter:junit-jupiter") } diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index 956d64e..715ddb8 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -1,5 +1,6 @@ package org.labs; +import lombok.extern.slf4j.Slf4j; import org.labs.io.ParamsReader; import org.labs.service.FoodService; import org.labs.service.QueueService; @@ -11,6 +12,7 @@ import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; import static org.labs.io.ParamsReader.WAITERS_COUNT; +@Slf4j public class Main { public static void main(String[] args) { var reader = new ParamsReader(); @@ -36,8 +38,8 @@ public static void main(String[] args) { Thread.currentThread().interrupt(); } - System.out.println("Симуляция завершена. Сколько поел каждый:"); + log.info("Симуляция завершена. Сколько поел каждый:"); foodService.getProgrammerIdToSoupCount().forEach((id, count) -> - System.out.println("Программист " + id + " поел " + count + " раз")); + log.info("Программист {} поел {} раз", id, count)); } } \ No newline at end of file diff --git a/src/main/java/org/labs/Simulation.java b/src/main/java/org/labs/Simulation.java index 1d07659..0484378 100644 --- a/src/main/java/org/labs/Simulation.java +++ b/src/main/java/org/labs/Simulation.java @@ -1,5 +1,6 @@ package org.labs; +import lombok.extern.slf4j.Slf4j; import org.labs.model.Fork; import org.labs.model.Programmer; import org.labs.model.Waiter; @@ -15,6 +16,7 @@ import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; import static org.labs.io.ParamsReader.WAITERS_COUNT; +@Slf4j public class Simulation { private final Map params; private final QueueService queueService; @@ -30,7 +32,7 @@ public Simulation(Map params, QueueService queueService, FoodSe } public void run(ExecutorService waiters, ExecutorService programmers) { - System.out.println("Начали симуляцию"); + log.info("Начали симуляцию"); foodService.initSoups(params.get(PROGRAMMERS_COUNT)); fillForks(params.get(PROGRAMMERS_COUNT)); fillProgrammers(params.get(PROGRAMMERS_COUNT), programmers); @@ -61,3 +63,5 @@ private void createWaiters(int waitersCount, ExecutorService executor) { } } } + +// 1 3 5 4 2 1 5 3 4 2 \ No newline at end of file diff --git a/src/main/java/org/labs/model/Fork.java b/src/main/java/org/labs/model/Fork.java index 185d1ff..8a49aa2 100644 --- a/src/main/java/org/labs/model/Fork.java +++ b/src/main/java/org/labs/model/Fork.java @@ -1,18 +1,21 @@ package org.labs.model; +import lombok.extern.slf4j.Slf4j; + import java.util.concurrent.locks.Lock; +@Slf4j public record Fork( int id, Lock lock ) { public void pickUp(int programmerId) { lock.lock(); - System.out.println("Программист " + programmerId + " взял вилку с id " + id); + log.info("Программист {} взял вилку с id {}", programmerId, id); } public void pickDown(int programmerId) { lock.unlock(); - System.out.println("Программист " + programmerId + " положил вилку с id " + id); + log.info("Программист {} положил вилку с id {}", programmerId, id); } } diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java index 7c180dd..8918613 100644 --- a/src/main/java/org/labs/model/Programmer.java +++ b/src/main/java/org/labs/model/Programmer.java @@ -4,13 +4,13 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.labs.service.FoodService; import org.labs.service.QueueService; -import java.util.concurrent.atomic.AtomicInteger; - @Getter @RequiredArgsConstructor +@Slf4j public class Programmer implements Runnable { private final int id; @Setter @@ -20,8 +20,6 @@ public class Programmer implements Runnable { @Setter private Fork right; - private AtomicInteger ateSoups = new AtomicInteger(0); - private final FoodService foodService; private final QueueService queueService; @@ -30,42 +28,49 @@ public class Programmer implements Runnable { public void run() { while (foodService.getEatCount().get() > 0) { this.state = State.HUNGRY; + log.info("Программист: {}, осталось еды - {}", id, foodService.getEatCount()); while (!foodService.hasSoup(id)) { if (foodService.getEatCount().get() < 1) { break; } - - System.out.println("Нет супа, программист с id = " + id + " не может поесть. Он будет ждать, когда пополнится порция"); - if (!queueService.contains(id)) { + log.info("Нет супа, программист с id = {} не может поесть. Он будет ждать, когда пополнится порция", id); + if (queueService.contains(id)) { + log.warn("Программист {} уже в очереди", id); + } + if (!queueService.contains(id) && foodService.getEatCount().get() > 0) { queueService.put(id); } + Thread.sleep(100); // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон } - try { - left.pickUp(id); - right.pickUp(id); - this.state = State.EATING; - System.out.println("Программист " + id + " начал кушать суп"); - foodService.disableSoup(id); - ateSoups.incrementAndGet(); - // Здесь можно добавить Thread.sleep() для симуляции времени еды, если нужно - } finally { - right.pickDown(id); - left.pickDown(id); - System.out.println("Программист " + id + " положил вилки"); - } + if (foodService.hasSoup(id) && foodService.getEatCount().get() > 0) { + try { + left.pickUp(id); + right.pickUp(id); - System.out.println("Программист " + id + " начал разговаривать"); - this.state = State.TALKING; - Thread.sleep(100); + state = State.EATING; - System.out.println("Осталось еды - " + foodService.getEatCount()); - } + log.info("Программист {} начал кушать суп", id); + + foodService.disableSoup(id); - foodService.addCount(id, ateSoups.get()); + } finally { + log.info("Программист {} закончил есть суп и собирается положить вилки", id); + right.pickDown(id); + left.pickDown(id); + + log.info("Программист {} положил вилки", id); + } + + log.info("Программист {} начал разговаривать", id); + + state = State.TALKING; + Thread.sleep(100); + } + } // он должен думать // посмотреть, есть ли у него суп // если нет - попросить официанта налить и продолжить думать diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java index 7606e28..e262405 100644 --- a/src/main/java/org/labs/model/Waiter.java +++ b/src/main/java/org/labs/model/Waiter.java @@ -2,10 +2,12 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.labs.service.FoodService; import org.labs.service.QueueService; @RequiredArgsConstructor +@Slf4j public class Waiter implements Runnable { private final int id; private final QueueService queueService; @@ -15,13 +17,15 @@ public class Waiter implements Runnable { @SneakyThrows public void run() { while (foodService.getEatCount().get() > 0) { - System.out.println("Официант " + id + ", его очередь = "); - queueService.print(); + log.info("Официант {}, его очередь = {}", id, queueService.print()); var programmerId = queueService.poll(); - System.out.println("Официант " + id + " взял программиста с id = " + programmerId); + log.info("Официант {} взял программиста с id = {}", id, programmerId); if (programmerId != null) { - foodService.addSoupToProgrammer(programmerId); - System.out.println("Официант " + id + " добавил программисту " + programmerId + " суп"); + if (foodService.addSoupToProgrammer(programmerId)) { + log.info("Официант {} добавил программисту {} суп", id, programmerId); + } else { + break; + } } Thread.sleep(100); } diff --git a/src/main/java/org/labs/service/FoodService.java b/src/main/java/org/labs/service/FoodService.java index 81e1bdd..284a5ec 100644 --- a/src/main/java/org/labs/service/FoodService.java +++ b/src/main/java/org/labs/service/FoodService.java @@ -1,35 +1,36 @@ package org.labs.service; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +@Getter +@Slf4j public class FoodService { private final AtomicInteger eatCount; - private final Map programmerIdToSoupAvailable; - private final Map programmerIdToSoupCount; + private final Map programmerIdToSoupAvailable = new ConcurrentHashMap<>(); + private final Map programmerIdToSoupCount = new ConcurrentHashMap<>(); + private final Lock lock = new ReentrantLock(); public FoodService(int eatCount) { this.eatCount = new AtomicInteger(eatCount); - this.programmerIdToSoupAvailable = new ConcurrentHashMap<>(); - this.programmerIdToSoupCount = new ConcurrentHashMap<>(); - } - - public AtomicInteger getEatCount() { - return eatCount; - } - - public Map getProgrammerIdToSoupCount() { - return programmerIdToSoupCount; } - public void addCount(int programmerId, int count) { - this.programmerIdToSoupCount.put(programmerId, count); + public void incrementSoupCountByProgrammerId(int programmerId) { + this.programmerIdToSoupCount.put( + programmerId, + programmerIdToSoupCount.getOrDefault(programmerId, 0) + 1 + ); } public void initSoups(int programmersCount) { for (int i = 0; i < programmersCount; i++) { - programmerIdToSoupAvailable.put(i + 1, true); + programmerIdToSoupAvailable.put(i + 1, false); } } @@ -37,14 +38,21 @@ public boolean hasSoup(int programmerId) { return programmerIdToSoupAvailable.get(programmerId); } - public synchronized void addSoupToProgrammer(int programmerId) { - if (eatCount.get() > 0) { - programmerIdToSoupAvailable.put(programmerId, true); - eatCount.decrementAndGet(); + public boolean addSoupToProgrammer(int programmerId) { + if (eatCount.get() == 0) { + return false; } + eatCount.decrementAndGet(); + programmerIdToSoupAvailable.put(programmerId, true); + log.info("Программист {} получил порцию супа. Осталось порций: {}", programmerId, eatCount.get()); + incrementSoupCountByProgrammerId(programmerId); + getProgrammerIdToSoupCount().forEach((id, count) -> + log.warn("Программист {} поел {} раз", id, count)); + return true; } public void disableSoup(int programmerId) { + log.info("Программист {} съел порцию супа", programmerId); programmerIdToSoupAvailable.put(programmerId, false); } } diff --git a/src/main/java/org/labs/service/QueueService.java b/src/main/java/org/labs/service/QueueService.java index 8bc0e7f..7ac70ba 100644 --- a/src/main/java/org/labs/service/QueueService.java +++ b/src/main/java/org/labs/service/QueueService.java @@ -6,11 +6,7 @@ @Getter public class QueueService { - private final ConcurrentLinkedQueue queue; - - public QueueService() { - this.queue = new ConcurrentLinkedQueue<>(); - } + private final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); public void put(Integer programmerId) { this.queue.add(programmerId); @@ -28,11 +24,7 @@ public boolean contains(Integer programmerId) { return this.queue.contains(programmerId); } - public void remove() { - this.queue.remove(); - } - - public void print() { - System.out.println(queue); + public String print() { + return this.queue.toString(); } } diff --git a/src/main/java/org/labs/service/WaiterService.java b/src/main/java/org/labs/service/WaiterService.java deleted file mode 100644 index 33efea2..0000000 --- a/src/main/java/org/labs/service/WaiterService.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.labs.service; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.labs.model.Waiter; - -import java.util.List; - -@Getter -@RequiredArgsConstructor -public class WaiterService { - private final List waiters; - - -} diff --git a/src/main/resources/params b/src/main/resources/params index 95d6698..1fdbd3a 100644 --- a/src/main/resources/params +++ b/src/main/resources/params @@ -1,3 +1,3 @@ -programmers_count=5 -eat_count=50 -waiters_count=2 +programmers_count=3 +eat_count=10 +waiters_count=7 From b6738c91b138fbc5af2bf4910b2a63de994c9459 Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Mon, 22 Sep 2025 18:24:06 +0300 Subject: [PATCH 8/9] add timeout_ms param to config --- src/main/java/org/labs/Simulation.java | 13 +++++++------ src/main/java/org/labs/io/ParamsReader.java | 3 ++- src/main/java/org/labs/model/Programmer.java | 5 +++-- src/main/java/org/labs/model/Waiter.java | 3 ++- src/main/resources/params | 3 ++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/labs/Simulation.java b/src/main/java/org/labs/Simulation.java index 0484378..56ed0ed 100644 --- a/src/main/java/org/labs/Simulation.java +++ b/src/main/java/org/labs/Simulation.java @@ -14,6 +14,7 @@ import java.util.concurrent.locks.ReentrantLock; import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; +import static org.labs.io.ParamsReader.TIMEOUT_MS; import static org.labs.io.ParamsReader.WAITERS_COUNT; @Slf4j @@ -35,8 +36,8 @@ public void run(ExecutorService waiters, ExecutorService programmers) { log.info("Начали симуляцию"); foodService.initSoups(params.get(PROGRAMMERS_COUNT)); fillForks(params.get(PROGRAMMERS_COUNT)); - fillProgrammers(params.get(PROGRAMMERS_COUNT), programmers); - createWaiters(params.get(WAITERS_COUNT), waiters); + fillProgrammers(params.get(PROGRAMMERS_COUNT), programmers, params.get(TIMEOUT_MS)); + createWaiters(params.get(WAITERS_COUNT), waiters, params.get(TIMEOUT_MS)); } private void fillForks(int forksCount) { @@ -45,9 +46,9 @@ private void fillForks(int forksCount) { } } - private void fillProgrammers(int programmersCount, ExecutorService executor) { + private void fillProgrammers(int programmersCount, ExecutorService executor, long timeoutMs) { for (int i = 0; i < programmersCount; i++) { - var programmer = new Programmer(i + 1, foodService, queueService); + var programmer = new Programmer(i + 1, foodService, queueService, timeoutMs); programmer.setState(Programmer.State.HUNGRY); var left = forks.get(i); var right = forks.get((i + 1) % programmersCount); @@ -57,9 +58,9 @@ private void fillProgrammers(int programmersCount, ExecutorService executor) { } } - private void createWaiters(int waitersCount, ExecutorService executor) { + private void createWaiters(int waitersCount, ExecutorService executor, long timeoutMs) { for (int i = 0; i < waitersCount; i++) { - executor.submit(new Waiter(i + 1, queueService, foodService)); + executor.submit(new Waiter(i + 1, queueService, foodService, timeoutMs)); } } } diff --git a/src/main/java/org/labs/io/ParamsReader.java b/src/main/java/org/labs/io/ParamsReader.java index e834497..71704ed 100644 --- a/src/main/java/org/labs/io/ParamsReader.java +++ b/src/main/java/org/labs/io/ParamsReader.java @@ -11,8 +11,9 @@ public class ParamsReader { public static final String PROGRAMMERS_COUNT = "programmers_count"; public static final String EAT_COUNT = "eat_count"; public static final String WAITERS_COUNT = "waiters_count"; + public static final String TIMEOUT_MS = "timeout_ms"; - private static final Set PARAMS_NAMES = Set.of(PROGRAMMERS_COUNT, EAT_COUNT, WAITERS_COUNT); + private static final Set PARAMS_NAMES = Set.of(PROGRAMMERS_COUNT, EAT_COUNT, WAITERS_COUNT, TIMEOUT_MS); private static final String SEPARATOR = "="; diff --git a/src/main/java/org/labs/model/Programmer.java b/src/main/java/org/labs/model/Programmer.java index 8918613..187fdc3 100644 --- a/src/main/java/org/labs/model/Programmer.java +++ b/src/main/java/org/labs/model/Programmer.java @@ -22,6 +22,7 @@ public class Programmer implements Runnable { private final FoodService foodService; private final QueueService queueService; + private final long timeoutMs; @Override @SneakyThrows @@ -42,7 +43,7 @@ public void run() { queueService.put(id); } - Thread.sleep(100); + Thread.sleep(timeoutMs); // сказать, что нет супа и дождаться, пока он появиться, то есть кинуть поток в сон } @@ -68,7 +69,7 @@ public void run() { log.info("Программист {} начал разговаривать", id); state = State.TALKING; - Thread.sleep(100); + Thread.sleep(timeoutMs); } } // он должен думать diff --git a/src/main/java/org/labs/model/Waiter.java b/src/main/java/org/labs/model/Waiter.java index e262405..500aa15 100644 --- a/src/main/java/org/labs/model/Waiter.java +++ b/src/main/java/org/labs/model/Waiter.java @@ -12,6 +12,7 @@ public class Waiter implements Runnable { private final int id; private final QueueService queueService; private final FoodService foodService; + private final long timeoutMs; @Override @SneakyThrows @@ -27,7 +28,7 @@ public void run() { break; } } - Thread.sleep(100); + Thread.sleep(timeoutMs); } } } diff --git a/src/main/resources/params b/src/main/resources/params index 1fdbd3a..33c3e1f 100644 --- a/src/main/resources/params +++ b/src/main/resources/params @@ -1,3 +1,4 @@ programmers_count=3 -eat_count=10 +eat_count=3000 waiters_count=7 +timeout_ms=10 From 0c581a32092140c6c404ba1e5333d085636c69ed Mon Sep 17 00:00:00 2001 From: "a.k.lysenko" Date: Tue, 23 Sep 2025 18:01:54 +0300 Subject: [PATCH 9/9] fix params reader --- src/main/java/org/labs/Main.java | 6 ++--- src/main/java/org/labs/Simulation.java | 13 +++++---- .../configuration/ConfigurationParam.java | 27 +++++++++++++++++++ src/main/java/org/labs/io/ParamsReader.java | 15 +++-------- 4 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/labs/configuration/ConfigurationParam.java diff --git a/src/main/java/org/labs/Main.java b/src/main/java/org/labs/Main.java index 715ddb8..8df915b 100644 --- a/src/main/java/org/labs/Main.java +++ b/src/main/java/org/labs/Main.java @@ -8,9 +8,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import static org.labs.io.ParamsReader.EAT_COUNT; -import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; -import static org.labs.io.ParamsReader.WAITERS_COUNT; +import static org.labs.configuration.ConfigurationParam.EAT_COUNT; +import static org.labs.configuration.ConfigurationParam.PROGRAMMERS_COUNT; +import static org.labs.configuration.ConfigurationParam.WAITERS_COUNT; @Slf4j public class Main { diff --git a/src/main/java/org/labs/Simulation.java b/src/main/java/org/labs/Simulation.java index 56ed0ed..137cb22 100644 --- a/src/main/java/org/labs/Simulation.java +++ b/src/main/java/org/labs/Simulation.java @@ -1,6 +1,7 @@ package org.labs; import lombok.extern.slf4j.Slf4j; +import org.labs.configuration.ConfigurationParam; import org.labs.model.Fork; import org.labs.model.Programmer; import org.labs.model.Waiter; @@ -13,19 +14,19 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.locks.ReentrantLock; -import static org.labs.io.ParamsReader.PROGRAMMERS_COUNT; -import static org.labs.io.ParamsReader.TIMEOUT_MS; -import static org.labs.io.ParamsReader.WAITERS_COUNT; +import static org.labs.configuration.ConfigurationParam.PROGRAMMERS_COUNT; +import static org.labs.configuration.ConfigurationParam.TIMEOUT_MS; +import static org.labs.configuration.ConfigurationParam.WAITERS_COUNT; @Slf4j public class Simulation { - private final Map params; + private final Map params; private final QueueService queueService; private final FoodService foodService; private final List forks; - public Simulation(Map params, QueueService queueService, FoodService foodService) { + public Simulation(Map params, QueueService queueService, FoodService foodService) { this.params = params; this.queueService = queueService; this.foodService = foodService; @@ -64,5 +65,3 @@ private void createWaiters(int waitersCount, ExecutorService executor, long time } } } - -// 1 3 5 4 2 1 5 3 4 2 \ No newline at end of file diff --git a/src/main/java/org/labs/configuration/ConfigurationParam.java b/src/main/java/org/labs/configuration/ConfigurationParam.java new file mode 100644 index 0000000..49ec189 --- /dev/null +++ b/src/main/java/org/labs/configuration/ConfigurationParam.java @@ -0,0 +1,27 @@ +package org.labs.configuration; + +import lombok.Getter; + +@Getter +public enum ConfigurationParam { + PROGRAMMERS_COUNT("programmers_count"), + EAT_COUNT("eat_count"), + WAITERS_COUNT("waiters_count"), + TIMEOUT_MS("timeout_ms"), + ; + + private final String value; + + ConfigurationParam(String value) { + this.value = value; + } + + public static ConfigurationParam fromValue(String value) { + for (ConfigurationParam param : values()) { + if (param.value.equals(value)) { + return param; + } + } + throw new IllegalArgumentException("No enum constant with value " + value); + } +} diff --git a/src/main/java/org/labs/io/ParamsReader.java b/src/main/java/org/labs/io/ParamsReader.java index 71704ed..48c0e4f 100644 --- a/src/main/java/org/labs/io/ParamsReader.java +++ b/src/main/java/org/labs/io/ParamsReader.java @@ -1,29 +1,22 @@ package org.labs.io; +import org.labs.configuration.ConfigurationParam; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; public class ParamsReader { - public static final String PROGRAMMERS_COUNT = "programmers_count"; - public static final String EAT_COUNT = "eat_count"; - public static final String WAITERS_COUNT = "waiters_count"; - public static final String TIMEOUT_MS = "timeout_ms"; - - private static final Set PARAMS_NAMES = Set.of(PROGRAMMERS_COUNT, EAT_COUNT, WAITERS_COUNT, TIMEOUT_MS); - private static final String SEPARATOR = "="; - public Map getParamsAsMap(String filePath) { + public Map getParamsAsMap(String filePath) { try (var lines = Files.lines(Paths.get(filePath))) { return lines .map(line -> line.split(SEPARATOR)) - .filter(val -> PARAMS_NAMES.contains(val[0])) .collect(Collectors.toMap( - values -> values[0], + values -> ConfigurationParam.fromValue(values[0]), values -> Integer.parseInt(values[1]) )); } catch (IOException e) {