Files
SSPR_25/buslaev_roman_lab_1
2025-03-13 11:07:17 +04:00
..
2025-03-13 11:07:17 +04:00
2025-03-13 11:07:17 +04:00

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

Разработка многопоточного приложения с использованием Java Concurrency. Мой вариант -> 4) Определить минимальный элемент матрицы.

Цель

Сравнить время выполнения трех реализаций алгоритма поиска минимального элемента в большой матрице:

  1. Однопоточный алгоритм.
  2. Многопоточный алгоритм с использованием ThreadPoolExecutor.
  3. Многопоточный алгоритм с использованием ForkJoinPool.

Все три алгоритма обрабатывают один и тот же массив, который генерируется один раз перед запуском.


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

  1. Генерация матрицы
    Метод generateMatrix(...) создает матрицу размером ROWS x COLS, заполняя ее случайными числами, используя Random.nextLong(MaxValue).

  2. Однопоточный поиск минимума

    • findMinSingleThread(...) обходит все строки и для каждой строки вызывает findMinInRaw(...) (локальный поиск минимума в одномерном массиве).
    • Возвращается общий минимальный элемент по всей матрице.
  3. Поиск минимума с ThreadPoolExecutor

    • findMinThreadPool(...) создает пул потоков из THREADS.
    • Для каждой строки матрицы отправляет задачу (Callable<Long>), которая в свою очередь вызывает findMinInRaw(...) для поиска минимума в одной строке.
    • Собираются результаты всех Future<Long>, ищется минимальный элемент из их значений.
  4. Поиск минимума с ForkJoinPool

    • findMinForkJoin(...) создает ForkJoinPool и запускает рекурсивную задачу MinTask.
    • MinTask (наследует RecursiveTask<Long>) делит промежуток строк на две части, пока не достигнет порога MAX_ROWS. Когда участок достаточно мал, последовательно ищет минимум по строкам.
    • Объединяет (берет минимум) из двух подзадач.
  5. Замер времени

    • В main(...) для каждого из трех алгоритмов замеряется время до и после выполнения (через System.nanoTime()).
    • Результаты выводятся в консоль.

Как запустить

  1. Установить JDK (Java 8 или выше).
  2. Скомпилировать:
    javac Main.java
    
  3. Запустить:
    java Main
    
  4. По завершении вы увидите три строки с минимальным элементом и временем выполнения (в мс) для:
    • Однопоточного алгоритма
    • Алгоритма с ThreadPoolExecutor
    • Алгоритма с ForkJoinPool

Пример вывода

Single: Min number - 0, Time: 107 мс
ThreadPoolExecutor: Min number - 0, Time: 102 мс
ForkJoinPool: Min number - 0, Time: 63 мс

Числа зависят от размера матрицы и мощности процессора. Чтобы было более наглядно видно разницу по времени между всеми реализации алгоритма, нужно более большую матрицу.


Вывод

  1. Однопоточный вариант прост в реализации, но при больших размерах матрицы работает долго.
  2. ThreadPoolExecutor позволяет распараллелить обработку строк матрицы и значительно ускорить поиск.
  3. ForkJoinPool часто дает еще более высокое ускорение за счет механизма рекурсивного разбиения задач, но реальная производительность зависит от конфигурации процессоров и параметров разбиения.