Merge pull request 'ПИбд-21 Валиулов Ильяс Айдарович Лабораторная №1' (#4) from Ilyas/SSPR_25:valiulov_ilyas_lab_1 into main

Reviewed-on: sevastyan_b/SSPR_25#4
This commit is contained in:
sevastyan_b 2025-02-27 22:27:36 +04:00
commit 50a0e379d3
5 changed files with 178 additions and 0 deletions

View File

@ -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<Integer> {
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);
}
}
}
}

View File

@ -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, так как это связано с тем, что матрицу довольно просто
разделить на подзадачи.

View File

@ -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;
}
}

View File

@ -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<Integer>[] 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<Integer> 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;
}
}

View File

@ -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;
}
}