From 74fa24789ac32f3ca2404381c667871ca1ac7938 Mon Sep 17 00:00:00 2001 From: IlyasValiulov <148232695+IlyasValiulov@users.noreply.github.com> Date: Thu, 27 Feb 2025 19:12:43 +0400 Subject: [PATCH] valiulov_ilyas_lab_1 is ready --- .idea/.gitignore | 3 ++ valiulov_ilyas_lab_1/ForkJoin.java | 44 ++++++++++++++++++++++++ valiulov_ilyas_lab_1/README.md | 44 ++++++++++++++++++++++++ valiulov_ilyas_lab_1/SingleThreaded.java | 13 +++++++ valiulov_ilyas_lab_1/ThreadPool.java | 40 +++++++++++++++++++++ valiulov_ilyas_lab_1/main.java | 37 ++++++++++++++++++++ 6 files changed, 181 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 valiulov_ilyas_lab_1/ForkJoin.java create mode 100644 valiulov_ilyas_lab_1/README.md create mode 100644 valiulov_ilyas_lab_1/SingleThreaded.java create mode 100644 valiulov_ilyas_lab_1/ThreadPool.java create mode 100644 valiulov_ilyas_lab_1/main.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/valiulov_ilyas_lab_1/ForkJoin.java b/valiulov_ilyas_lab_1/ForkJoin.java new file mode 100644 index 0000000..fca9777 --- /dev/null +++ b/valiulov_ilyas_lab_1/ForkJoin.java @@ -0,0 +1,44 @@ +import java.util.concurrent.*; + +public class ForkJoin { + public static int findMax(int[][] matrix) { + ForkJoinPool pool = new ForkJoinPool(); + return pool.invoke(new MaxTask(matrix, 0, matrix.length)); + } + + private static class MaxTask extends RecursiveTask { + private final int[][] matrix; + private final int startRow; + private final int endRow; + + MaxTask(int[][] matrix, int startRow, int endRow) { + this.matrix = matrix; + this.startRow = startRow; + this.endRow = endRow; + } + + @Override + protected Integer compute() { + if (endRow - startRow <= 100) { + int max = Integer.MIN_VALUE; + for (int i = startRow; i < endRow; i++) { + for (int j = 0; j < matrix[i].length; j++) { + if (matrix[i][j] > max) { + max = matrix[i][j]; + } + } + } + return max; + } + else { + int mid = (startRow + endRow) / 2; + MaxTask left = new MaxTask(matrix, startRow, mid); + MaxTask right = new MaxTask(matrix, mid, endRow); + left.fork(); + int rightResult = right.compute(); + int leftResult = left.join(); + return Math.max(leftResult, rightResult); + } + } + } +} \ No newline at end of file diff --git a/valiulov_ilyas_lab_1/README.md b/valiulov_ilyas_lab_1/README.md new file mode 100644 index 0000000..6150142 --- /dev/null +++ b/valiulov_ilyas_lab_1/README.md @@ -0,0 +1,44 @@ +## Лабораторная работа №1. + +Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания: + +Вариант 5: Нужно определить максимальный элемент матрицы + +**Необходимо:** + +1. Разработать однопоточный вариант алгоритма и замерить время его работы. +2. Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы +3. Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы. + +**Запуск лабораторной работы** +> javac main.java SingleThreaded.java ThreadPool.java ForkJoin.java +> java main + +**Используемые технологии** +* java.util.concurrent - библиотека для разработки многопоточных программ + +**Что делает программа** +1. Генерируем матрицу +2. Находим максимальный элемент матрицы в однопоточном алгоритме и замеряем время работы алгоритма +3. То же самое с помощью ThreadPoolExecutor и ForkJoinPool + +**Тесты** + +Размерность матрицы 1000*1000\ +Single-threaded time: 17 ms\ +ThreadPoolExecutor time: 73 ms\ +ForkJoinPool time: 36 ms + +Размерность матрицы 10000*10000\ +Single-threaded time: 1639 ms\ +ThreadPoolExecutor time: 1440 ms\ +ForkJoinPool time: 464 ms + +**Вывод** + +Для небольших задач реализация многопоточности приводит к более худшему результату, так как ее реализация требует дополнительных затрат + +Однако при больших задачах эти дополнительные затраты незначительны по сравнению с эффективностью паралельной обработки + +При работе с матрицами ForkJoinPool эффективней, чем ThreadedPoolExecutor, так как это связано с тем, что матрицу довольно просто +разделить на подзадачи. diff --git a/valiulov_ilyas_lab_1/SingleThreaded.java b/valiulov_ilyas_lab_1/SingleThreaded.java new file mode 100644 index 0000000..bfce848 --- /dev/null +++ b/valiulov_ilyas_lab_1/SingleThreaded.java @@ -0,0 +1,13 @@ +public class SingleThreaded { + public static int findMax(int[][] matrix) { + int max = Integer.MIN_VALUE; + for (int[] row : matrix) { + for (int value : row) { + if (value > max) { + max = value; + } + } + } + return max; + } +} \ No newline at end of file diff --git a/valiulov_ilyas_lab_1/ThreadPool.java b/valiulov_ilyas_lab_1/ThreadPool.java new file mode 100644 index 0000000..6198625 --- /dev/null +++ b/valiulov_ilyas_lab_1/ThreadPool.java @@ -0,0 +1,40 @@ +import java.util.concurrent.*; + +public class ThreadPool { + public static int findMax(int[][] matrix, int numThreads) throws InterruptedException, ExecutionException { + ExecutorService executor = Executors.newFixedThreadPool(numThreads); + int rows = matrix.length; + int cols = matrix[0].length; + int chunkSize = rows / numThreads; + Future[] futures = new Future[numThreads]; + + for (int i = 0; i < numThreads; i++) { + int startRow = i * chunkSize; + int endRow = (i == numThreads - 1) ? rows : startRow + chunkSize; + futures[i] = executor.submit(() -> findMaxInRange(matrix, startRow, endRow)); + } + + int max = Integer.MIN_VALUE; + for (Future future : futures) { + int localMax = future.get(); + if (localMax > max) { + max = localMax; + } + } + + executor.shutdown(); + return max; + } + + private static int findMaxInRange(int[][] matrix, int startRow, int endRow) { + int max = Integer.MIN_VALUE; + for (int i = startRow; i < endRow; i++) { + for (int j = 0; j < matrix[i].length; j++) { + if (matrix[i][j] > max) { + max = matrix[i][j]; + } + } + } + return max; + } +} diff --git a/valiulov_ilyas_lab_1/main.java b/valiulov_ilyas_lab_1/main.java new file mode 100644 index 0000000..6c9982a --- /dev/null +++ b/valiulov_ilyas_lab_1/main.java @@ -0,0 +1,37 @@ +import java.util.Random; +import java.util.concurrent.*; + +public class main { + public static void main(String[] args) throws InterruptedException, ExecutionException { + int[][] matrix = generateMatrix(1000, 1000); + + long startTime = System.nanoTime(); + int singleThreadedMax = SingleThreaded.findMax(matrix); + long endTime = System.nanoTime(); + System.out.println("Single-threaded max: " + singleThreadedMax); + System.out.println("Single-threaded time: " + (endTime - startTime) + " ns"); + + startTime = System.nanoTime(); + int threadPoolMax = ThreadPool.findMax(matrix, 10); + endTime = System.nanoTime(); + System.out.println("ThreadPoolExecutor max: " + threadPoolMax); + System.out.println("ThreadPoolExecutor time: " + (endTime - startTime) + " ns"); + + startTime = System.nanoTime(); + int forkJoinMax = ForkJoin.findMax(matrix); + endTime = System.nanoTime(); + System.out.println("ForkJoinPool max: " + forkJoinMax); + System.out.println("ForkJoinPool time: " + (endTime - startTime) + " ns"); + } + + public static int[][] generateMatrix(int rows, int cols) { + int[][] matrix = new int[rows][cols]; + Random random = new Random(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + matrix[i][j] = random.nextInt(10000); + } + } + return matrix; + } +}