Лабораторная работа №1.

Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания.

Необходимо выполнить следующие задачи:

Разработать однопоточный вариант алгоритма и замерить время его работы.
Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы
Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы.

Вариант задания
8)Найти максимальный элемент выше главной диагонали.

Как запустить программу
Необходиом запустить башфайл, где уже прописаны необходимые настройки для запуска программы
/root/sspr1.sh 

Инструменты

Язык программирования: Java
Пакеты:
java.util.concurrent — используется для реализации многопоточности через ThreadPoolExecutor и ForkJoinPool
Среда разработки: IntelliJ IDEA
Версия JDK: 21

Описание работы программы

Генерация матрицы
Программа генерирует случайную матрицу заданного размера (количество строк и столбцов передается как аргументы командной строки).
Матрица заполняется случайными целыми числами.

Однопоточный алгоритм

Алгоритм проходит по всем элементам матрицы, находящимся выше главной диагонали.
Для каждого элемента проверяется, больше ли он текущего максимума.
Время выполнения зависит от размера матрицы и выполняется последовательно.

Многопоточный алгоритм с использованием ThreadPoolExecutor

Каждая строка матрицы обрабатывается в отдельном потоке.
Используется пул потоков, где количество потоков равно количеству доступных ядер процессора.
Каждый поток находит максимум в своей строке выше главной диагонали.
После завершения всех потоков находится глобальный максимум.

Многопоточный алгоритм с использованием ForkJoinPool

Используется рекурсивное разделение задачи на подзадачи.
Матрица делится на две части, и каждая часть обрабатывается отдельно.
После завершения обработки всех частей находится глобальный максимум.
Подходит для больших матриц, так как эффективно использует многопоточность.

Замер времени

Для каждого алгоритма замеряется время выполнения.
Результаты выводятся на экран.

Результаты работы на матрице 10000 × 10000

Тест	Однопоточный алгоритм	ThreadPoolExecutor	ForkJoinPool
Тест №1	1615 мс	740 мс	1040 мс
Тест №2	1789 мс	743 мс	1020 мс
Тест №3	1613 мс	696 мс	1068 мс

Результаты работы на матрице 5000 × 5000

Тест	Однопоточный алгоритм	ThreadPoolExecutor	ForkJoinPool
Тест №1	420 мс	210 мс	280 мс
Тест №2	435 мс	205 мс	275 мс
Тест №3	410 мс	215 мс	290 мс

Результаты работы на матрице 2000 × 2000

Тест	Однопоточный алгоритм	ThreadPoolExecutor	ForkJoinPool
Тест №1	65 мс	35 мс	45 мс
Тест №2	68 мс	34 мс	46 мс
Тест №3	67 мс	36 мс	44 мс

Вывод

Для небольших матриц (например, 100 × 100) разница во времени выполнения может быть незначительной.
Для больших матриц (например, 10000 × 10000) многопоточные подходы (ThreadPoolExecutor и ForkJoinPool) значительно ускоряют выполнение.
Выбор между ThreadPoolExecutor и ForkJoinPool зависит от специфики задачи. Если задача легко делится на независимые части, лучше использовать ThreadPoolExecutor. Если задача требует рекурсивного разделения, подойдет ForkJoinPool.