Лабораторная №1
Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания. Необходимо: 1 Разработать однопоточный вариант алгоритма и замерить время его работы. 2 Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы 3 Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы. ВАЖНО: Массив генерируется до работы всех вариантов алгоритмов. Все три алгоритма обрабатывают три одинаковых массива.
Вариант и задание
22 Упорядочить столбцы матрицы по возрастанию первых элементов.
Как запустить лабораторную работу
Минимальная требуемая версия jdk - 21.0.2 Для запуска лабораторной работы нужно в директории с java файлами (внутри папки src) выполнить следующее:
-
javac -d /путь/к/выходной/директории *.java
- перейти к выходной директории при помощи команды cd
- внутри директории с .class файлами нужно выполнить команду:
-
java Main
Какие технологии использовались
В этой лабораторной использовалась следующие пакеты:
- java.util.concurrent — инструменты для многопоточности (пулы потоков, синхронизация).
- ForkJoinPool — пул потоков для параллельных задач по принципу "разделяй и властвуй".
- RecursiveAction — задача без возврата результата, которую можно разбить на подзадачи.
- Logger — журнал для логирования сообщений и ошибок.
Что она делает
Согласно заданию программа создает матрицу состоящую из 5000 строчек и 5000 столбцов. Программа реализует сортировку слиянием за тем исключением, что при перестановке перестановки осуществляются столбцами. Я попытался создать некое подобие класса-управленца, ArrayController, но выглядит так, будто это лишнее.
Тесты
Для тестов был создан отдельный метод в классе Main, который прогоняет 2 матрицы для каждого алгоритма сортировки. Программа генерирует и сортирует большую матрицу только тогда, когда тесты успешно проходят. Сами тесты:
Пример 1
Входные данные
{3, 8, 4, 10, 2, 1,102},
{2, 423, 41, 53,123,421,123},
{1312,214, 5, 1, 23, 4, 5}
Входные данные
{ 1, 2, 3, 4, 8, 10, 102},
{421, 123, 2, 41, 423, 53, 123 },
{ 4, 23, 1312, 5, 214, 1, 5}
Пример 2
Входные данные
{ 7, 12, 5, 2, 98, 33, 9},
{ 45, 3, 67, 89, 1, 4, 8},
{200, 50, 150, 25, 175, 75, 5}
Выходные данные
{ 2, 5, 7, 9, 12, 33, 98 },
{ 89, 67, 45, 8, 3, 4, 1 },
{ 25,150, 200, 5, 50, 75, 175 }
Результаты работы на матрице 5000 на 5000
Время выполнения без потоков: 3728.2977 мс
Время выполнения с потоками ThreadExecutor: 1541.1539 мс
Время выполнения с потоками ForkJoinPool: 1412.6938 мс
Время выполнения без потоков: 4043.893 мс
Время выполнения с потоками ThreadExecutor: 1624.9124 мс
Время выполнения с потоками ForkJoinPool: 1474.203 мс
Время выполнения без потоков: 3876.2693 мс
Время выполнения с потоками ThreadExecutor: 1354.9933 мс
Время выполнения с потоками ForkJoinPool: 1433.2023 мс
Вывод
Оба варианта работа с потоками работают в более чем два раза быстрее чем без потоков. Между собой 3 запуска программы показало, что в большинстве случаев ForkJoinPool справляется быстрее, чем ThreadExecutor. Скорее всего это связано с тем, что ForkJoinPool использует тот же принцип "Разделяй и влавствуй", что и сортировка слиянием.