forked from sevastyan_b/SSPR_25
183 lines
8.8 KiB
Markdown
183 lines
8.8 KiB
Markdown
# Лабораторная работа №1.
|
||
|
||
**Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания.**
|
||
|
||
Необходимо выполнить следующие задачи:
|
||
|
||
1. Разработать однопоточный вариант алгоритма и замерить время его работы.
|
||
2. Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы
|
||
3. Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы.
|
||
|
||
## Вариант задания
|
||
|
||
21. Упорядочить столбцы матрицы по убыванию первых элементов.
|
||
|
||
## Как запустить программу
|
||
|
||
1. Для начала, необходимо локально создать аналогичную (или собственную) иерархию файлов программы:
|
||
|
||
Например:
|
||
|
||
- project_java (название директории/проекта)
|
||
|
||
- /src (папка с файлами программы, но необязательна)
|
||
|
||
- ForkJoinSorter.java
|
||
- Main.java
|
||
- MatrixUtils.java
|
||
- SingleThreadSorter.java
|
||
- ThreadPoolSorter.java
|
||
|
||
2. Далее, необходимо скопировать код из каждого файла, расположенного в удалённой ветке на гите, в локальные файлы, находящиеся внутри директории _src_.
|
||
|
||
3. Внутри директории, где расположены файлы программы (например, _src_), с помощью командной строки скомпилировать программу следующей командой:
|
||
|
||
> javac Main.java
|
||
|
||
4. Убедившись, что компиляция прошла успешно (никаких ошибок в процессе компиляции не возникло), запустить программу следующей командой:
|
||
|
||
> java Main.java <кол-во строк матрицы (целое число)> <кол-во столбцов матрицы (целое число)>
|
||
|
||
**Внимание:**
|
||
|
||
Можно скомпилировать программу, указав в качестве доп. параметра выходную директории (то есть папку, куда, в конечном итоге, будет скомпилирована программа). И далее, перейти в эту папку, и оттуда запустить программу:
|
||
|
||
> javac -d /путь/к/выходной/директории Main.java
|
||
|
||
> java Main.java <кол-во строк матрицы (целое число)> <кол-во столбцов матрицы (целое число)>
|
||
|
||
## Инструменты
|
||
|
||
- **Язык программирования**: Java
|
||
- **Пакеты**:
|
||
- `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 показал наименьшее время выполнения, потому что он эффективно распределяет задачи между несколькими потоками, уменьшая время ожидания на обработку каждого столбца матрицы.
|
||
|
||
В целом использование потоков ускоряет выполнение, так как позволяет параллельно обрабатывать несколько частей данных, в отличие от последовательной обработки без потоков.
|