From 24bf5f45a79ee19671b7daa863d51c667b9cdb74 Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:51:07 +0000 Subject: [PATCH 1/6] 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 bf1bcff6acb802afb7e4eb3243b032b4480d3621 Mon Sep 17 00:00:00 2001 From: Viktor Shamin Date: Wed, 24 Sep 2025 13:28:46 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=20?= =?UTF-8?q?=D0=BE=D0=B1=20=D0=BE=D0=B1=D0=B5=D0=B4=D0=B0=D1=8E=D1=89=D0=B8?= =?UTF-8?q?=D1=85=20=D1=84=D0=B8=D0=BB=D0=BE=D1=81=D0=BE=D1=84=D0=B0=D1=85?= =?UTF-8?q?=20(v.=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/labs/lab1/Developer.java | 58 ++++++++++++++++++++++ src/main/java/org/labs/lab1/Lunch.java | 51 +++++++++++++++++++ src/main/java/org/labs/lab1/Spoon.java | 13 +++++ src/main/java/org/labs/lab1/Waiter.java | 53 ++++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 src/main/java/org/labs/lab1/Developer.java create mode 100644 src/main/java/org/labs/lab1/Lunch.java create mode 100644 src/main/java/org/labs/lab1/Spoon.java create mode 100644 src/main/java/org/labs/lab1/Waiter.java diff --git a/src/main/java/org/labs/lab1/Developer.java b/src/main/java/org/labs/lab1/Developer.java new file mode 100644 index 0000000..7703ee4 --- /dev/null +++ b/src/main/java/org/labs/lab1/Developer.java @@ -0,0 +1,58 @@ +package org.labs.lab1; + +import java.util.concurrent.ThreadLocalRandom; + +public class Developer implements Runnable { + + private final int id; + private final Spoon leftSpoon; + private final Spoon rightSpoon; + private final Waiter waiter; + private int eaten = 0; + + public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Waiter waiter) { + this.id = id; + this.leftSpoon = leftSpoon; + this.rightSpoon = rightSpoon; + this.waiter = waiter; + } + + @Override + public void run() { + while (true) { + Integer dish = waiter.getDish(); + if (dish == null) { + System.out.println("Программист " + id + " закончил обед. Съел порций: " + eaten); + return; + } + + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(20, 60)); + } catch (InterruptedException e) { + System.out.println("Программиста " + id + " прервали на обсуждении."); + return; + } + + Spoon first = leftSpoon; + Spoon second = rightSpoon; + if (first.getId() > second.getId()) { + Spoon tmp = first; + first = second; + second = tmp; + } + + try { + synchronized (first) { + synchronized (second) { + eaten++; + System.out.println("Программист " + id + " ест блюдо #" + dish); + Thread.sleep(100); + } + } + } catch (InterruptedException e) { + System.out.println("Программиста " + id + " прервали на поедании блюда #" + dish); + return; + } + } + } +} diff --git a/src/main/java/org/labs/lab1/Lunch.java b/src/main/java/org/labs/lab1/Lunch.java new file mode 100644 index 0000000..9c27690 --- /dev/null +++ b/src/main/java/org/labs/lab1/Lunch.java @@ -0,0 +1,51 @@ +package org.labs.lab1; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +public class Lunch { + + public static AtomicInteger REMAINING_FOOD = new AtomicInteger(1000); + + public static void main(String[] args) { + Lunch lab = new Lunch(); + lab.startLunch(); + } + + private void startLunch() { + int devCount = 7; + + ExecutorService executorService = Executors.newCachedThreadPool(); + + Waiter waiter1 = new Waiter(1); + Waiter waiter2 = new Waiter(2); + + executorService.execute(waiter1); + executorService.execute(waiter2); + + Developer[] devs = getDevs(devCount, waiter1, waiter2); + + for (Developer dev : devs) { + executorService.execute(dev); + } + + executorService.shutdown(); + } + + private static Developer[] getDevs(int devCount, Waiter waiter1, Waiter waiter2) { + Developer[] devs = new Developer[devCount]; + + Spoon leftSpoon = new Spoon(0); + + for (int i = 0; i < devCount; i++) { + Spoon rightSpoon = new Spoon(i + 1); + Waiter waiter = (i % 2 == 0) ? waiter1 : waiter2; + devs[i] = new Developer(i, leftSpoon, rightSpoon, waiter); + leftSpoon = rightSpoon; + } + + return devs; + } +} + diff --git a/src/main/java/org/labs/lab1/Spoon.java b/src/main/java/org/labs/lab1/Spoon.java new file mode 100644 index 0000000..8e95f72 --- /dev/null +++ b/src/main/java/org/labs/lab1/Spoon.java @@ -0,0 +1,13 @@ +package org.labs.lab1; + +public class Spoon { + private final int id; + + public Spoon(int id) { + this.id = id; + } + + public int getId() { + return id; + } +} diff --git a/src/main/java/org/labs/lab1/Waiter.java b/src/main/java/org/labs/lab1/Waiter.java new file mode 100644 index 0000000..065fa42 --- /dev/null +++ b/src/main/java/org/labs/lab1/Waiter.java @@ -0,0 +1,53 @@ +package org.labs.lab1; + +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; + +public class Waiter implements Runnable { + + private final int id; + private final SynchronousQueue dishes = new SynchronousQueue<>(); + + public Waiter(int id) { + this.id = id; + } + + @Override + public void run() { + while (true) { + int next = Lunch.REMAINING_FOOD.getAndDecrement(); + + if (next <= 0) { + break; + } + + try { + dishes.put(next); + } catch (InterruptedException e) { + System.out.println("Вставка официантом " + id + " блюда #" + next + " была прервана"); + Thread.currentThread().interrupt(); + return; + } + } + } + + public Integer getDish() { + try { + while (true) { + Integer dish = dishes.poll(200, TimeUnit.MILLISECONDS); + + if (dish != null) { + return dish; + } + + if (Lunch.REMAINING_FOOD.get() <= 0) { + return null; + } + } + } catch (InterruptedException e) { + System.out.println("Получение официантом " + id + " блюда было прервано"); + Thread.currentThread().interrupt(); + return null; + } + } +} From bedcafb8aa0f169d532b4c193b4486358b7ade26 Mon Sep 17 00:00:00 2001 From: Viktor Shamin Date: Thu, 2 Oct 2025 00:01:55 +0300 Subject: [PATCH 3/6] stash --- src/main/java/org/labs/lab1/Developer.java | 12 ++++++------ src/main/java/org/labs/lab1/Lunch.java | 4 +++- src/main/java/org/labs/lab1/Waiter.java | 10 ++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/labs/lab1/Developer.java b/src/main/java/org/labs/lab1/Developer.java index 7703ee4..979076f 100644 --- a/src/main/java/org/labs/lab1/Developer.java +++ b/src/main/java/org/labs/lab1/Developer.java @@ -19,13 +19,9 @@ public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Waiter waiter) { @Override public void run() { - while (true) { - Integer dish = waiter.getDish(); - if (dish == null) { - System.out.println("Программист " + id + " закончил обед. Съел порций: " + eaten); - return; - } + Integer dish = waiter.getDish(); + while (dish != null || eaten < Lunch.FOOD_PER_DEV) { try { Thread.sleep(ThreadLocalRandom.current().nextInt(20, 60)); } catch (InterruptedException e) { @@ -53,6 +49,10 @@ public void run() { System.out.println("Программиста " + id + " прервали на поедании блюда #" + dish); return; } + + dish = waiter.getDish(); } + + System.out.println("Программист " + id + " закончил обед. Съел порций: " + eaten); } } diff --git a/src/main/java/org/labs/lab1/Lunch.java b/src/main/java/org/labs/lab1/Lunch.java index 9c27690..1866d42 100644 --- a/src/main/java/org/labs/lab1/Lunch.java +++ b/src/main/java/org/labs/lab1/Lunch.java @@ -6,7 +6,8 @@ public class Lunch { - public static AtomicInteger REMAINING_FOOD = new AtomicInteger(1000); + public final static AtomicInteger REMAINING_FOOD = new AtomicInteger(500); + public static int FOOD_PER_DEV; public static void main(String[] args) { Lunch lab = new Lunch(); @@ -15,6 +16,7 @@ public static void main(String[] args) { private void startLunch() { int devCount = 7; + FOOD_PER_DEV = (REMAINING_FOOD.get() + devCount - 1) / devCount; ExecutorService executorService = Executors.newCachedThreadPool(); diff --git a/src/main/java/org/labs/lab1/Waiter.java b/src/main/java/org/labs/lab1/Waiter.java index 065fa42..387c239 100644 --- a/src/main/java/org/labs/lab1/Waiter.java +++ b/src/main/java/org/labs/lab1/Waiter.java @@ -14,13 +14,9 @@ public Waiter(int id) { @Override public void run() { - while (true) { - int next = Lunch.REMAINING_FOOD.getAndDecrement(); - - if (next <= 0) { - break; - } + int next = Lunch.REMAINING_FOOD.getAndDecrement(); + while (next > 0) { try { dishes.put(next); } catch (InterruptedException e) { @@ -28,6 +24,8 @@ public void run() { Thread.currentThread().interrupt(); return; } + + next = Lunch.REMAINING_FOOD.getAndDecrement(); } } From 7e9d1b5a675b97f9c5e76e8550e923ed98f3839d Mon Sep 17 00:00:00 2001 From: Viktor Shamin Date: Thu, 2 Oct 2025 13:07:43 +0300 Subject: [PATCH 4/6] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=89=D1=83=D1=8E=20=D0=BA=D1=83=D1=85=D0=BD?= =?UTF-8?q?=D1=8E,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3?= =?UTF-8?q?=D1=83=D1=80=D0=B0=D1=86=D0=B8=D0=B8,=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=82=D1=8C=20=D1=8D=D0=BA=D0=B7=D0=B5=D0=BA?= =?UTF-8?q?=D1=8C=D1=8E=D1=82=D0=BE=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/labs/lab1/Developer.java | 19 ++-- src/main/java/org/labs/lab1/Lunch.java | 88 ++++++++++++++----- src/main/java/org/labs/lab1/Spoon.java | 11 +-- .../java/org/labs/lab1/ThreadPoolType.java | 8 ++ src/main/java/org/labs/lab1/Waiter.java | 27 +++--- src/main/resources/application.properties | 4 + 6 files changed, 107 insertions(+), 50 deletions(-) create mode 100644 src/main/java/org/labs/lab1/ThreadPoolType.java create mode 100644 src/main/resources/application.properties diff --git a/src/main/java/org/labs/lab1/Developer.java b/src/main/java/org/labs/lab1/Developer.java index 979076f..e318779 100644 --- a/src/main/java/org/labs/lab1/Developer.java +++ b/src/main/java/org/labs/lab1/Developer.java @@ -19,9 +19,7 @@ public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Waiter waiter) { @Override public void run() { - Integer dish = waiter.getDish(); - - while (dish != null || eaten < Lunch.FOOD_PER_DEV) { + while (eaten < Lunch.FOOD_PER_DEV) { try { Thread.sleep(ThreadLocalRandom.current().nextInt(20, 60)); } catch (InterruptedException e) { @@ -29,9 +27,17 @@ public void run() { return; } + Integer dish = waiter.getDish(); + if (dish == null) { + if (Lunch.REMAINING_FOOD.get() <= 0 && waiter.isKitchenEmpty()) { + return; + } + continue; + } + Spoon first = leftSpoon; Spoon second = rightSpoon; - if (first.getId() > second.getId()) { + if (first.id() > second.id()) { Spoon tmp = first; first = second; second = tmp; @@ -42,15 +48,14 @@ public void run() { synchronized (second) { eaten++; System.out.println("Программист " + id + " ест блюдо #" + dish); - Thread.sleep(100); + System.out.println("Всего съел: " + eaten + "/" + Lunch.FOOD_PER_DEV); + Thread.sleep(ThreadLocalRandom.current().nextInt(60, 140)); } } } catch (InterruptedException e) { System.out.println("Программиста " + id + " прервали на поедании блюда #" + dish); return; } - - dish = waiter.getDish(); } System.out.println("Программист " + id + " закончил обед. Съел порций: " + eaten); diff --git a/src/main/java/org/labs/lab1/Lunch.java b/src/main/java/org/labs/lab1/Lunch.java index 1866d42..6e627c8 100644 --- a/src/main/java/org/labs/lab1/Lunch.java +++ b/src/main/java/org/labs/lab1/Lunch.java @@ -1,53 +1,97 @@ package org.labs.lab1; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; +import org.labs.Main; + public class Lunch { - public final static AtomicInteger REMAINING_FOOD = new AtomicInteger(500); public static int FOOD_PER_DEV; + public static AtomicInteger REMAINING_FOOD; + public static BlockingQueue KITCHEN; public static void main(String[] args) { - Lunch lab = new Lunch(); - lab.startLunch(); - } + Properties prop = new Properties(); + + try (InputStream input = Main.class.getClassLoader().getResourceAsStream("application.properties")) { + if (input == null) { + System.out.println("Файл application.properties не найден в ресурсах!"); + return; + } + prop.load(input); + } catch (FileNotFoundException e) { + System.out.println("Файл не найден"); + } catch (IOException e) { + System.out.println(e.getMessage()); + System.out.println("Проблемы ввода/вывода"); + } - private void startLunch() { - int devCount = 7; - FOOD_PER_DEV = (REMAINING_FOOD.get() + devCount - 1) / devCount; + int devCount = Integer.parseInt(prop.getProperty("devCount", "7")); + int waiterCount = Integer.parseInt(prop.getProperty("waiterCount", "2")); + int totalFood = Integer.parseInt(prop.getProperty("totalFood", "1000")); + String threadPoolTypeStr = prop.getProperty("threadPoolType", "SINGLE"); + ThreadPoolType threadPoolType = ThreadPoolType.valueOf(threadPoolTypeStr); - ExecutorService executorService = Executors.newCachedThreadPool(); + Lunch lunch = new Lunch(); + lunch.startLunch(devCount, waiterCount, totalFood, threadPoolType); + } + + private void startLunch(int devCount, int waiterCount, int totalFood, ThreadPoolType threadPoolType) { + REMAINING_FOOD = new AtomicInteger(totalFood); + FOOD_PER_DEV = (totalFood + devCount - 1) / devCount; + KITCHEN = new ArrayBlockingQueue<>(devCount); - Waiter waiter1 = new Waiter(1); - Waiter waiter2 = new Waiter(2); + ExecutorService executorService = switch (threadPoolType) { + case FIXED -> Executors.newFixedThreadPool(devCount + waiterCount); + case CACHED -> Executors.newCachedThreadPool(); + case WORK_STEALING -> Executors.newWorkStealingPool(devCount + waiterCount); + case SINGLE -> Executors.newSingleThreadExecutor(); + }; - executorService.execute(waiter1); - executorService.execute(waiter2); + long start = System.currentTimeMillis(); - Developer[] devs = getDevs(devCount, waiter1, waiter2); + Waiter[] waiters = new Waiter[waiterCount]; + for (int i = 0; i < waiterCount; i++) { + waiters[i] = new Waiter(i, KITCHEN); + executorService.execute(waiters[i]); + } + Developer[] devs = getDevs(devCount, waiters); for (Developer dev : devs) { executorService.execute(dev); } executorService.shutdown(); + try { + executorService.awaitTermination(5, TimeUnit.MINUTES); + } catch (InterruptedException e) { + System.out.println("Ожидание окончания работы было прервано"); + } + + long workingTime = System.currentTimeMillis() - start; + System.out.println(threadPoolType + " thread pool отработал за " + workingTime + " мс"); } - private static Developer[] getDevs(int devCount, Waiter waiter1, Waiter waiter2) { + private static Developer[] getDevs(int devCount, Waiter[] waiters) { Developer[] devs = new Developer[devCount]; - Spoon leftSpoon = new Spoon(0); + Spoon[] spoons = new Spoon[devCount]; + for (int i = 0; i < devCount; i++) { + spoons[i] = new Spoon(i); + } for (int i = 0; i < devCount; i++) { - Spoon rightSpoon = new Spoon(i + 1); - Waiter waiter = (i % 2 == 0) ? waiter1 : waiter2; - devs[i] = new Developer(i, leftSpoon, rightSpoon, waiter); - leftSpoon = rightSpoon; + Spoon left = spoons[i]; + Spoon right = spoons[(i + 1) % devCount]; + Waiter waiter = waiters[i % waiters.length]; + devs[i] = new Developer(i, left, right, waiter); } return devs; } } - diff --git a/src/main/java/org/labs/lab1/Spoon.java b/src/main/java/org/labs/lab1/Spoon.java index 8e95f72..142b5a4 100644 --- a/src/main/java/org/labs/lab1/Spoon.java +++ b/src/main/java/org/labs/lab1/Spoon.java @@ -1,13 +1,4 @@ package org.labs.lab1; -public class Spoon { - private final int id; - - public Spoon(int id) { - this.id = id; - } - - public int getId() { - return id; - } +public record Spoon(int id) { } diff --git a/src/main/java/org/labs/lab1/ThreadPoolType.java b/src/main/java/org/labs/lab1/ThreadPoolType.java new file mode 100644 index 0000000..ac0a4a3 --- /dev/null +++ b/src/main/java/org/labs/lab1/ThreadPoolType.java @@ -0,0 +1,8 @@ +package org.labs.lab1; + +public enum ThreadPoolType { + FIXED, + CACHED, + WORK_STEALING, + SINGLE +} diff --git a/src/main/java/org/labs/lab1/Waiter.java b/src/main/java/org/labs/lab1/Waiter.java index 387c239..255a753 100644 --- a/src/main/java/org/labs/lab1/Waiter.java +++ b/src/main/java/org/labs/lab1/Waiter.java @@ -1,15 +1,16 @@ package org.labs.lab1; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; public class Waiter implements Runnable { private final int id; - private final SynchronousQueue dishes = new SynchronousQueue<>(); + private final BlockingQueue dishes; - public Waiter(int id) { + public Waiter(int id, BlockingQueue dishes) { this.id = id; + this.dishes = dishes; } @Override @@ -31,21 +32,25 @@ public void run() { public Integer getDish() { try { - while (true) { - Integer dish = dishes.poll(200, TimeUnit.MILLISECONDS); + Integer dish = dishes.poll(200, TimeUnit.MILLISECONDS); - if (dish != null) { - return dish; - } + if (dish != null) { + return dish; + } - if (Lunch.REMAINING_FOOD.get() <= 0) { - return null; - } + if (Lunch.REMAINING_FOOD.get() <= 0 && dishes.isEmpty()) { + return null; } + + return null; } catch (InterruptedException e) { System.out.println("Получение официантом " + id + " блюда было прервано"); Thread.currentThread().interrupt(); return null; } } + + public boolean isKitchenEmpty() { + return dishes.isEmpty(); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..f52b525 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,4 @@ +devCount=7 +waiterCount=2 +totalFood=1000 +threadPoolType=WORK_STEALING \ No newline at end of file From b0aa72cfc2be371cc32bf8574e888e02dc262e80 Mon Sep 17 00:00:00 2001 From: Viktor Shamin Date: Sat, 4 Oct 2025 21:09:29 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D1=82=D1=8C=20=D0=BD=D0=B0=20PriorityBlockingQueue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/labs/lab1/Developer.java | 67 ++++++++++++---------- src/main/java/org/labs/lab1/Lunch.java | 13 ++--- src/main/java/org/labs/lab1/Waiter.java | 35 ++--------- 3 files changed, 47 insertions(+), 68 deletions(-) diff --git a/src/main/java/org/labs/lab1/Developer.java b/src/main/java/org/labs/lab1/Developer.java index e318779..6bd40b4 100644 --- a/src/main/java/org/labs/lab1/Developer.java +++ b/src/main/java/org/labs/lab1/Developer.java @@ -1,25 +1,26 @@ package org.labs.lab1; +import java.util.Queue; import java.util.concurrent.ThreadLocalRandom; -public class Developer implements Runnable { +public class Developer implements Comparable, Runnable { private final int id; private final Spoon leftSpoon; private final Spoon rightSpoon; - private final Waiter waiter; + private final Queue hungryDevs; private int eaten = 0; - public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Waiter waiter) { + public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Queue hungryDevs) { this.id = id; this.leftSpoon = leftSpoon; this.rightSpoon = rightSpoon; - this.waiter = waiter; + this.hungryDevs = hungryDevs; } @Override public void run() { - while (eaten < Lunch.FOOD_PER_DEV) { + while (Lunch.REMAINING_FOOD.get() > 0) { try { Thread.sleep(ThreadLocalRandom.current().nextInt(20, 60)); } catch (InterruptedException e) { @@ -27,37 +28,43 @@ public void run() { return; } - Integer dish = waiter.getDish(); - if (dish == null) { - if (Lunch.REMAINING_FOOD.get() <= 0 && waiter.isKitchenEmpty()) { - return; - } - continue; - } + hungryDevs.add(this); + } + } - Spoon first = leftSpoon; - Spoon second = rightSpoon; - if (first.id() > second.id()) { - Spoon tmp = first; - first = second; - second = tmp; - } + public void eat() { + Spoon first = leftSpoon; + Spoon second = rightSpoon; + if (first.id() > second.id()) { + Spoon tmp = first; + first = second; + second = tmp; + } - try { - synchronized (first) { - synchronized (second) { - eaten++; - System.out.println("Программист " + id + " ест блюдо #" + dish); - System.out.println("Всего съел: " + eaten + "/" + Lunch.FOOD_PER_DEV); - Thread.sleep(ThreadLocalRandom.current().nextInt(60, 140)); - } + try { + synchronized (first) { + synchronized (second) { + eaten++; + System.out.println("Программист " + id + ". Всего съел: " + eaten); + Thread.sleep(ThreadLocalRandom.current().nextInt(60, 140)); } - } catch (InterruptedException e) { - System.out.println("Программиста " + id + " прервали на поедании блюда #" + dish); - return; } + } catch (InterruptedException e) { + System.out.println("Программиста " + id + " прервали на поедании блюда #" + eaten); + return; } System.out.println("Программист " + id + " закончил обед. Съел порций: " + eaten); } + + @Override + public int compareTo(Developer o) { + if (this.eaten > o.eaten) { + return 1; + } else if (this.eaten < o.eaten) { + return -1; + } else { + return 0; + } + } } diff --git a/src/main/java/org/labs/lab1/Lunch.java b/src/main/java/org/labs/lab1/Lunch.java index 6e627c8..24c35b4 100644 --- a/src/main/java/org/labs/lab1/Lunch.java +++ b/src/main/java/org/labs/lab1/Lunch.java @@ -11,9 +11,8 @@ public class Lunch { - public static int FOOD_PER_DEV; public static AtomicInteger REMAINING_FOOD; - public static BlockingQueue KITCHEN; + public static BlockingQueue KITCHEN; public static void main(String[] args) { Properties prop = new Properties(); @@ -43,8 +42,7 @@ public static void main(String[] args) { private void startLunch(int devCount, int waiterCount, int totalFood, ThreadPoolType threadPoolType) { REMAINING_FOOD = new AtomicInteger(totalFood); - FOOD_PER_DEV = (totalFood + devCount - 1) / devCount; - KITCHEN = new ArrayBlockingQueue<>(devCount); + KITCHEN = new PriorityBlockingQueue<>(devCount); ExecutorService executorService = switch (threadPoolType) { case FIXED -> Executors.newFixedThreadPool(devCount + waiterCount); @@ -61,7 +59,7 @@ private void startLunch(int devCount, int waiterCount, int totalFood, ThreadPool executorService.execute(waiters[i]); } - Developer[] devs = getDevs(devCount, waiters); + Developer[] devs = getDevs(devCount); for (Developer dev : devs) { executorService.execute(dev); } @@ -77,7 +75,7 @@ private void startLunch(int devCount, int waiterCount, int totalFood, ThreadPool System.out.println(threadPoolType + " thread pool отработал за " + workingTime + " мс"); } - private static Developer[] getDevs(int devCount, Waiter[] waiters) { + private static Developer[] getDevs(int devCount) { Developer[] devs = new Developer[devCount]; Spoon[] spoons = new Spoon[devCount]; @@ -88,8 +86,7 @@ private static Developer[] getDevs(int devCount, Waiter[] waiters) { for (int i = 0; i < devCount; i++) { Spoon left = spoons[i]; Spoon right = spoons[(i + 1) % devCount]; - Waiter waiter = waiters[i % waiters.length]; - devs[i] = new Developer(i, left, right, waiter); + devs[i] = new Developer(i, left, right, KITCHEN); } return devs; diff --git a/src/main/java/org/labs/lab1/Waiter.java b/src/main/java/org/labs/lab1/Waiter.java index 255a753..4c13299 100644 --- a/src/main/java/org/labs/lab1/Waiter.java +++ b/src/main/java/org/labs/lab1/Waiter.java @@ -1,16 +1,14 @@ package org.labs.lab1; - import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; public class Waiter implements Runnable { private final int id; - private final BlockingQueue dishes; + private final BlockingQueue hungryDevs; - public Waiter(int id, BlockingQueue dishes) { + public Waiter(int id, BlockingQueue hungryDevs) { this.id = id; - this.dishes = dishes; + this.hungryDevs = hungryDevs; } @Override @@ -19,7 +17,8 @@ public void run() { while (next > 0) { try { - dishes.put(next); + Developer hungryDev = hungryDevs.take(); + hungryDev.eat(); } catch (InterruptedException e) { System.out.println("Вставка официантом " + id + " блюда #" + next + " была прервана"); Thread.currentThread().interrupt(); @@ -29,28 +28,4 @@ public void run() { next = Lunch.REMAINING_FOOD.getAndDecrement(); } } - - public Integer getDish() { - try { - Integer dish = dishes.poll(200, TimeUnit.MILLISECONDS); - - if (dish != null) { - return dish; - } - - if (Lunch.REMAINING_FOOD.get() <= 0 && dishes.isEmpty()) { - return null; - } - - return null; - } catch (InterruptedException e) { - System.out.println("Получение официантом " + id + " блюда было прервано"); - Thread.currentThread().interrupt(); - return null; - } - } - - public boolean isKitchenEmpty() { - return dishes.isEmpty(); - } } From b2de02c68699a2901189244971fb1de4e4aa15a8 Mon Sep 17 00:00:00 2001 From: Viktor Shamin Date: Sun, 5 Oct 2025 12:33:49 +0300 Subject: [PATCH 6/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=B0=20=D0=BE=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B4=D0=B8=20=D1=83=20=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/labs/lab1/Developer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/labs/lab1/Developer.java b/src/main/java/org/labs/lab1/Developer.java index 6bd40b4..9d207ff 100644 --- a/src/main/java/org/labs/lab1/Developer.java +++ b/src/main/java/org/labs/lab1/Developer.java @@ -1,6 +1,7 @@ package org.labs.lab1; import java.util.Queue; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadLocalRandom; public class Developer implements Comparable, Runnable { @@ -8,10 +9,10 @@ public class Developer implements Comparable, Runnable { private final int id; private final Spoon leftSpoon; private final Spoon rightSpoon; - private final Queue hungryDevs; + private final BlockingQueue hungryDevs; private int eaten = 0; - public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, Queue hungryDevs) { + public Developer(int id, Spoon leftSpoon, Spoon rightSpoon, BlockingQueue hungryDevs) { this.id = id; this.leftSpoon = leftSpoon; this.rightSpoon = rightSpoon;