# Лабораторная №1
Разработка многопоточного приложения с использованием Java Concurrency
согласно варианту задания.
Необходимо:
1 Разработать однопоточный вариант алгоритма и замерить время его работы.
2  Разработать параллельный вариант алгоритма с использованием
ThreadPoolExecutor и замерить время его работы 
3  Разработать параллельный вариант алгоритма с использованием ForkJoinPoll
и замерить время его работы.
ВАЖНО: Массив генерируется до работы всех вариантов алгоритмов. Все три
алгоритма обрабатывают три одинаковых массива. 

## Вариант и задание
17 Упорядочить строки матрицы по убыванию суммы элементов.

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

1. **Подсчёт сумм строк**: Для каждой строки матрицы вычисляется сумма её элементов.
2. **Сортировка строк**: Строки матрицы сортируются по убыванию суммы их элементов.

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

### Как запустить
```sh
javac MatrixSorter.java
java MatrixSorter
```

### Используемые технологии
Программа использует **Java Concurrency**, включая классы и интерфейсы:
- `ExecutorService`, `ThreadPoolExecutor`, `ForkJoinPool`, `Future`, `CompletableFuture`, `RecursiveAction` — для организации многопоточности.

### Что делает программа
1. Генерирует матрицу заданного размера, заполненную случайными значениями.
2. Вычисляет сумму элементов каждой строки.
3. Сортирует строки по убыванию их суммы.
4. Замеряет среднее время выполнения разных комбинаций подсчёта и сортировки.

---

## Анализ результатов

### Результаты в файле res.txt

### Маленькие матрицы (10 x 1000000, 100 x 100000)
- Использование многопоточности не даёт значительного прироста, так как оверхед на создание потоков превышает выгоду от распараллеливания.
- `ThreadPool` или `ForkJoin` для сортировки могут даже слегка ухудшать производительность из-за накладных расходов.

### Средние матрицы (1000 x 10000, 10000 x 1000)
- На этом размере многопоточное суммирование (`ThreadPool`, `ForkJoin`) начинает давать выгоду.
- `ForkJoin` работает стабильно, а `ThreadPool` может давать как ускорение, так и замедление.
- На сортировке многопоточность помогает, но эффект зависит от формы матрицы.

### Большие матрицы (100000 x 100, 1000000 x 10)
- Однопоточное выполнение становится крайне неэффективным.
- `ForkJoin` даёт лучшие результаты как при подсчёте, так и при сортировке.
- `ThreadPool` работает лучше однопоточного подхода, но хуже `ForkJoin`.

### Выводы
1. **Для маленьких матриц**: Однопоточное выполнение предпочтительнее, так как накладные расходы на многопоточность не окупаются.
2. **Для средних матриц**: Подсчёт можно распараллеливать (`ForkJoin` предпочтителен), сортировка зависит от формы матрицы.
3. **Для больших матриц**: Использование `ForkJoin` даёт наилучший результат как для подсчёта, так и для сортировки.
4. **Использование `ThreadPool`** может быть полезно, но его эффективность зависит от конкретных размеров матрицы.

