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

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

Вариант 5: Нужно определить максимальный элемент матрицы

**Необходимо:**

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

**Запуск лабораторной работы**
> javac main.java SingleThreaded.java ThreadPool.java ForkJoin.java
> java main

**Используемые технологии**
* java.util.concurrent - библиотека для разработки многопоточных программ

**Что делает программа**
1. Генерируем матрицу
2. Находим максимальный элемент матрицы в однопоточном алгоритме и замеряем время работы алгоритма
3. То же самое  с помощью ThreadPoolExecutor и ForkJoinPool

**Тесты**

Размерность матрицы 1000*1000\
Single-threaded time: 17 ms\
ThreadPoolExecutor time: 73 ms\
ForkJoinPool time: 36 ms

Размерность матрицы 10000*10000\
Single-threaded time: 1639 ms\
ThreadPoolExecutor time: 1440 ms\
ForkJoinPool time: 464 ms

**Вывод**

Для небольших задач реализация многопоточности приводит к более худшему результату, так как ее реализация требует дополнительных затрат

Однако при больших задачах эти дополнительные затраты незначительны по сравнению с эффективностью паралельной обработки

При работе с матрицами ForkJoinPool эффективней, чем ThreadedPoolExecutor, так как это связано с тем, что матрицу довольно просто
разделить на подзадачи.
