1. Для начала, необходимо локально создать аналогичную (или собственную) иерархию файлов программы:
Например:
- project_java (название директории/проекта)
- /src (папка с файлами программы, но необязательна)
- ForkJoinSorter.java
- Main.java
- MatrixUtils.java
- SingleThreadSorter.java
- ThreadPoolSorter.java
2. Далее, необходимо скопировать код из каждого файла, расположенного в удалённой ветке на гите, в локальные файлы, находящиеся внутри директории _src_.
3. Внутри директории, где расположены файлы программы (например, _src_), с помощью командной строки скомпилировать программу следующей командой:
> javac Main.java
4. Убедившись, что компиляция прошла успешно (никаких ошибок в процессе компиляции не возникло), запустить программу следующей командой:
Можно скомпилировать программу, указав в качестве доп. параметра выходную директории (то есть папку, куда, в конечном итоге, будет скомпилирована программа). И далее, перейти в эту папку, и оттуда запустить программу:
-`java.util.concurrent` — используется для реализации многопоточности через `ThreadPoolExecutor` и `ForkJoinPool`
- **Среда разработки**: IntelliJ IDEA
- **Версия JDK**: 21
- **Алгоритмы сортировки**:
- **Однопоточная сортировка** — реализована вручную с использованием сортировки столбцов
- **ThreadPoolExecutor** — для многопоточной обработки столбцов с использованием пула потоков
- **ForkJoinPool** — для многопоточной обработки столбцов с использованием рекурсивных задач
## Как работает программа
Программа выполняет сортировку столбцов матрицы по убыванию первых элементов с использованием различных подходов многозадачности:
1.**Однопоточная версия**: сортирует столбцы матрицы с использованием стандартной сортировки.
2.**Параллельная версия с использованием ThreadPoolExecutor**: выполняет сортировку столбцов с использованием пула потоков для ускорения работы.
3.**Параллельная версия с использованием ForkJoinPool**: использует рекурсивное разделение задач для оптимизации работы с большими массивами данных.
Программа генерирует случайную матрицу (с заданным размером), затем выполняет сортировку для каждого из вариантов и замеряет время выполнения каждого из алгоритмов. Результаты выводятся на экран и записываются в файл.
## Тесты
#### Пример №1
##### Входные данные
```
| 60 | 873 | 81 | 801 | 45 | 838 | 231 |
| 583 | 576 | 207 | 148 | 919 | 809 | 130 |
| 574 | 390 | 21 | 4 | 960 | 350 | 930 |
| 103 | 917 | 619 | 731 | 242 | 16 | 587 |
| 528 | 789 | 815 | 800 | 330 | 416 | 141 |
| 19 | 211 | 831 | 598 | 382 | 572 | 212 |
| 365 | 973 | 680 | 41 | 474 | 922 | 750 |
```
##### Выходные данные
```
| 873 | 838 | 801 | 231 | 81 | 60 | 45 |
| 576 | 809 | 148 | 130 | 207 | 583 | 919 |
| 390 | 350 | 4 | 930 | 21 | 574 | 960 |
| 917 | 16 | 731 | 587 | 619 | 103 | 242 |
| 789 | 416 | 800 | 141 | 815 | 528 | 330 |
| 211 | 572 | 598 | 212 | 831 | 19 | 382 |
| 973 | 922 | 41 | 750 | 680 | 365 | 474 |
```
#### Пример №2
##### Входные данные
```
| 549 | 708 | 958 | 340 | 836 | 575 | 748 |
| 235 | 699 | 906 | 895 | 731 | 957 | 936 |
| 776 | 690 | 156 | 377 | 985 | 995 | 995 |
| 906 | 713 | 410 | 559 | 760 | 694 | 158 |
| 16 | 474 | 825 | 784 | 141 | 59 | 443 |
| 447 | 909 | 521 | 406 | 845 | 66 | 229 |
| 582 | 473 | 856 | 439 | 166 | 721 | 676 |
```
##### Выходные данные
```
| 958 | 836 | 748 | 708 | 575 | 549 | 340 |
| 906 | 731 | 936 | 699 | 957 | 235 | 895 |
| 156 | 985 | 995 | 690 | 995 | 776 | 377 |
| 410 | 760 | 158 | 713 | 694 | 906 | 559 |
| 825 | 141 | 443 | 474 | 59 | 16 | 784 |
| 521 | 845 | 229 | 909 | 66 | 447 | 406 |
| 856 | 166 | 676 | 473 | 721 | 582 | 439 |
```
#### Пример №3
##### Входные данные
```
| 901 | 186 | 700 | 766 | 397 | 422 | 762 |
| 575 | 966 | 882 | 884 | 220 | 440 | 201 |
| 850 | 660 | 909 | 964 | 257 | 177 | 800 |
| 977 | 495 | 832 | 426 | 592 | 769 | 170 |
| 994 | 769 | 347 | 784 | 56 | 225 | 643 |
| 739 | 327 | 700 | 714 | 721 | 157 | 404 |
| 240 | 612 | 992 | 855 | 811 | 756 | 230 |
```
##### Выходные данные
```
| 901 | 766 | 762 | 700 | 422 | 397 | 186 |
| 575 | 884 | 201 | 882 | 440 | 220 | 966 |
| 850 | 964 | 800 | 909 | 177 | 257 | 660 |
| 977 | 426 | 170 | 832 | 769 | 592 | 495 |
| 994 | 784 | 643 | 347 | 225 | 56 | 769 |
| 739 | 714 | 404 | 700 | 157 | 721 | 327 |
| 240 | 855 | 230 | 992 | 756 | 811 | 612 |
```
## Результаты работы на матрице 10000 \* 10000
#### Тест №1
```
Время сортировки (однопоточный режим): 1615 мс
Время сортировки (ThreadPoolExecutor): 740 мс
Время сортировки (ForkJoinPool): 1040 мс
```
#### Тест №2
```
Время сортировки (однопоточный режим): 1789 мс
Время сортировки (ThreadPoolExecutor): 743 мс
Время сортировки (ForkJoinPool): 1020 мс
```
#### Тест №3
```
Время сортировки (однопоточный режим): 1613 мс
Время сортировки (ThreadPoolExecutor): 696 мс
Время сортировки (ForkJoinPool): 1068 мс
```
## Вывод
ThreadExecutor показал наименьшее время выполнения, потому что он эффективно распределяет задачи между несколькими потоками, уменьшая время ожидания на обработку каждого столбца матрицы.
В целом использование потоков ускоряет выполнение, так как позволяет параллельно обрабатывать несколько частей данных, в отличие от последовательной обработки без потоков.