Лабораторная работа №1.
Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания. Необходимо:
- Разработать однопоточный вариант алгоритма и замерить время его работы.
- Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы
- Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы. ВАЖНО: Массив генерируется до работы всех вариантов алгоритмов. Все три алгоритма обрабатывают три одинаковых массива.
Вариант 13 Определить сумму из произведений элементов каждой строки матрицы.
Запуск программы javac MatrixSumOfProducts.java java MatrixSumOfProducts
Используемые технологии *java.util.concurrent — библиотека для разработки многопоточных программ. *BigInteger — для работы с большими числами, чтобы избежать переполнения при умножении.
Что делает программа
-
Генерирует матрицу заданного размера.
-
Вычисляет сумму произведений элементов каждой строки матрицы:
2.1 Однопоточным алгоритмом.
2.2 Параллельным алгоритмом с использованием ThreadPoolExecutor.
2.3 Параллельным алгоритмом с использованием ForkJoinPool.
- Замеряет время выполнения каждого из алгоритмов.
Тесты
Размерность матрицы 100x100
Single-threaded time: 17 ms
ThreadPoolExecutor time: 73 ms
ForkJoinPool time: 36 ms
Размерность матрицы 1000x1000
Single-threaded time: 1639 ms
ThreadPoolExecutor time: 1440 ms
ForkJoinPool time: 464 ms
Вывод
Для небольших задач реализация многопоточности может приводить к более худшему результату, так как ее реализация требует дополнительных затрат на создание и управление потоками. Однако при увеличении размера задачи многопоточные алгоритмы начинают показывать свою эффективность за счет параллельной обработки данных.
Наблюдения:
- Однопоточный алгоритм работает быстрее на небольших матрицах (например, 100x100), так как отсутствуют накладные расходы на создание и синхронизацию потоков.
- ThreadPoolExecutor показывает хорошие результаты на больших матрицах (например, 1000x1000), но его производительность может быть ниже, чем у
ForkJoinPool, из-за менее эффективного распределения задач между потоками. - ForkJoinPool демонстрирует наилучшую производительность на больших задачах, так как он оптимизирован для рекурсивного разделения задач и эффективного использования ресурсов процессора.