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

Необходимо:
1) Разработать однопоточный вариант алгоритма и замерить время его работы.
2) Разработать параллельный вариант алгоритма с использованием
   ThreadPoolExecutor и замерить время его работы
3) Разработать параллельный вариант алгоритма с использованием ForkJoinPoll
   и замерить время его работы.

Массив генерируется до работы всех вариантов алгоритмов. Все три
алгоритма обрабатывают три одинаковых массива.

## Вариант и задание
2. Разделить элементы матрицы на наименьший элемент.

### Описание
Данная программа разработана для сравнения производительности однопоточного и многопоточного подходов к делению
элементов матрицы на среднее арифметическое её элементов. Задача состоит из двух основных частей:
1. Нахождение наименьшего элемента в матрице
2. Деление элементов матрицы на наименьший элемент в матрице

Эти этапы выполняются с разными вариантами многопоточности, чтобы выявить их влияние на производительность.

### Как запустить
java MinDivisionTask

### Используемые технологии
Программа использует Java Concurrency, включая классы и интерфейсы:
1) ExecutorService
2) RecursiveAction
3) ForkJoinPool
ThreadPoolExecutor был реализован вручную

### Что делает программа
1. Генерирует матрицу заданного размера, заполненную случайными значениями.
2. Находит наименьший элемент в матрице.
3. Делит все элементы матрицы на наименьший элемент в матрице.
4. Замеряет время выполнения для однопоточного и двух многопоточных (ThreadPoolExecutor, ForkJoinPool) алгоритмов.

## Результаты тестов
(SingleThreadedTime - Однопоточный алгоритм)

### Для матрцы 4000*4000:
{Тест 1} SingleThreadedTime: 80 ThreadPoolExecutorTime: 78 ForkJoinPoolTime: 64
{Тест 2} SingleThreadedTime: 45 ThreadPoolExecutorTime: 39 ForkJoinPoolTime: 64
{Тест 3} SingleThreadedTime: 37 ThreadPoolExecutorTime: 31 ForkJoinPoolTime: 32
{Тест 4} SingleThreadedTime: 32 ThreadPoolExecutorTime: 40 ForkJoinPoolTime: 46
{Тест 5} SingleThreadedTime: 43 ThreadPoolExecutorTime: 32 ForkJoinPoolTime: 50
{Тест 6} SingleThreadedTime: 44 ThreadPoolExecutorTime: 29 ForkJoinPoolTime: 45
{Тест 7} SingleThreadedTime: 45 ThreadPoolExecutorTime: 31 ForkJoinPoolTime: 45
{Тест 8} SingleThreadedTime: 44 ThreadPoolExecutorTime: 31 ForkJoinPoolTime: 47
{Тест 9} SingleThreadedTime: 43 ThreadPoolExecutorTime: 31 ForkJoinPoolTime: 45
{Тест 10} SingleThreadedTime: 43 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 11} SingleThreadedTime: 34 ThreadPoolExecutorTime: 31 ForkJoinPoolTime: 32
{Тест 12} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 13} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 31
{Тест 14} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 15} SingleThreadedTime: 32 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 16} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 17} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 32
{Тест 18} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 31
{Тест 19} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 31
{Тест 20} SingleThreadedTime: 31 ThreadPoolExecutorTime: 30 ForkJoinPoolTime: 31
Среднее время:
SingleThreadedTime: 38
ThreadPoolExecutorTime: 33
ForkJoinPoolTime: 39

### Для матрцы 11000*11000:
{Тест 1} SingleThreadedTime: 402 ThreadPoolExecutorTime: 259 ForkJoinPoolTime: 271
{Тест 2} SingleThreadedTime: 406 ThreadPoolExecutorTime: 273 ForkJoinPoolTime: 236
{Тест 3} SingleThreadedTime: 388 ThreadPoolExecutorTime: 245 ForkJoinPoolTime: 226
{Тест 4} SingleThreadedTime: 237 ThreadPoolExecutorTime: 329 ForkJoinPoolTime: 339
{Тест 5} SingleThreadedTime: 333 ThreadPoolExecutorTime: 251 ForkJoinPoolTime: 227
{Тест 6} SingleThreadedTime: 330 ThreadPoolExecutorTime: 231 ForkJoinPoolTime: 220
{Тест 7} SingleThreadedTime: 344 ThreadPoolExecutorTime: 234 ForkJoinPoolTime: 224
{Тест 8} SingleThreadedTime: 330 ThreadPoolExecutorTime: 224 ForkJoinPoolTime: 224
{Тест 9} SingleThreadedTime: 329 ThreadPoolExecutorTime: 222 ForkJoinPoolTime: 220
{Тест 10} SingleThreadedTime: 336 ThreadPoolExecutorTime: 230 ForkJoinPoolTime: 239
{Тест 11} SingleThreadedTime: 238 ThreadPoolExecutorTime: 223 ForkJoinPoolTime: 222
{Тест 12} SingleThreadedTime: 238 ThreadPoolExecutorTime: 223 ForkJoinPoolTime: 234
{Тест 13} SingleThreadedTime: 243 ThreadPoolExecutorTime: 241 ForkJoinPoolTime: 223
{Тест 14} SingleThreadedTime: 253 ThreadPoolExecutorTime: 223 ForkJoinPoolTime: 224
{Тест 15} SingleThreadedTime: 235 ThreadPoolExecutorTime: 223 ForkJoinPoolTime: 223
{Тест 16} SingleThreadedTime: 243 ThreadPoolExecutorTime: 222 ForkJoinPoolTime: 223
{Тест 17} SingleThreadedTime: 236 ThreadPoolExecutorTime: 221 ForkJoinPoolTime: 221
{Тест 18} SingleThreadedTime: 234 ThreadPoolExecutorTime: 225 ForkJoinPoolTime: 233
{Тест 19} SingleThreadedTime: 238 ThreadPoolExecutorTime: 221 ForkJoinPoolTime: 221
{Тест 20} SingleThreadedTime: 241 ThreadPoolExecutorTime: 223 ForkJoinPoolTime: 225
Среднее время:
SingleThreadedTime: 291
ThreadPoolExecutorTime: 237
ForkJoinPoolTime: 233

## Вывод 
 В ходе анализа производительности алгоритмов обработки матриц разного размера выяснилось, что многопоточные алгоритмы
не всегда оказываются быстрее однопоточных, особенно при работе с небольшими матрицами. В таких случаях многопоточные
алгоритмы, использующие ThreadPoolExecutor и ForkJoinPool, показывают более плохие результаты из-за дополнительных 
затрат на создание потоков и управление ими. 
 Но когда размеры матриц увеличиваются, многопоточные алгоритмы начинают показывать гораздо лучшую производительность 
по сравнению с однопоточным. Однопоточный алгоритм начинает замедляться из-за большого объема данных, тогда как 
многопоточные алгоритмы, начинают работать быстрее. Это происходит потому, что затраты на управление потоками 
оправдываются их параллельной работой, что позволяет значительно ускорить обработку данных.
 Вообщем, многопоточность действительно может значительно повысить производительность при обработке больших объемов 
данных.