bartasova_ksenia_lab_1 ready
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.RecursiveAction;
|
||||
|
||||
public class ForkJoinMatrixProcessor {
|
||||
private static class MatrixTask extends RecursiveAction {
|
||||
private final double[][] matrix;
|
||||
private final int startRow, endRow;
|
||||
private final double average;
|
||||
|
||||
MatrixTask(double[][] matrix, int startRow, int endRow, double average) {
|
||||
this.matrix = matrix;
|
||||
this.startRow = startRow;
|
||||
this.endRow = endRow;
|
||||
this.average = average;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if (endRow - startRow <= 10) { // Базовый случай: обрабатываем небольшой блок
|
||||
for (int i = startRow; i < endRow; i++) {
|
||||
for (int j = 0; j < matrix[i].length; j++) {
|
||||
matrix[i][j] /= average;
|
||||
}
|
||||
}
|
||||
} else { // Рекурсивный случай: разбиваем задачу на две части
|
||||
int mid = (startRow + endRow) / 2;
|
||||
invokeAll(
|
||||
new MatrixTask(matrix, startRow, mid, average),
|
||||
new MatrixTask(matrix, mid, endRow, average)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void process(double[][] matrix) {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
|
||||
// Вычисляем среднее арифметическое
|
||||
double sum = 0;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
sum += matrix[i][j];
|
||||
}
|
||||
}
|
||||
double average = sum / (rows * cols);
|
||||
|
||||
// Создаем и запускаем задачу в ForkJoinPool
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(new MatrixTask(matrix, 0, rows, average));
|
||||
pool.shutdown();
|
||||
}
|
||||
}
|
||||
38
bartasova_ksenia_lab_1/Lab_1_sspr/src/Main.java
Normal file
38
bartasova_ksenia_lab_1/Lab_1_sspr/src/Main.java
Normal file
@@ -0,0 +1,38 @@
|
||||
public class Main {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
int rows = 1000;
|
||||
int cols = 1000;
|
||||
double[][] matrix = MatrixGenerator.generateMatrix(rows, cols);
|
||||
|
||||
// Однопоточный вариант
|
||||
double[][] singleThreadedMatrix = copyMatrix(matrix);
|
||||
long startTime = System.nanoTime();
|
||||
SingleThreadedMatrixProcessor.process(singleThreadedMatrix);
|
||||
long endTime = System.nanoTime();
|
||||
System.out.println("Single-threaded: " + (endTime - startTime) / 1e9 + " сек");
|
||||
|
||||
// Параллельный вариант с ThreadPoolExecutor
|
||||
double[][] threadPoolMatrix = copyMatrix(matrix);
|
||||
startTime = System.nanoTime();
|
||||
ThreadPoolMatrixProcessor.process(threadPoolMatrix, 4); // 4 потока
|
||||
endTime = System.nanoTime();
|
||||
System.out.println("ThreadPoolExecutor: " + (endTime - startTime) / 1e9 + " сек");
|
||||
|
||||
// Параллельный вариант с ForkJoinPool
|
||||
double[][] forkJoinMatrix = copyMatrix(matrix);
|
||||
startTime = System.nanoTime();
|
||||
ForkJoinMatrixProcessor.process(forkJoinMatrix);
|
||||
endTime = System.nanoTime();
|
||||
System.out.println("ForkJoinPool: " + (endTime - startTime) / 1e9 + " сек");
|
||||
}
|
||||
|
||||
private static double[][] copyMatrix(double[][] matrix) {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
double[][] copy = new double[rows][cols];
|
||||
for (int i = 0; i < rows; i++) {
|
||||
System.arraycopy(matrix[i], 0, copy[i], 0, cols);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
14
bartasova_ksenia_lab_1/Lab_1_sspr/src/MatrixGenerator.java
Normal file
14
bartasova_ksenia_lab_1/Lab_1_sspr/src/MatrixGenerator.java
Normal file
@@ -0,0 +1,14 @@
|
||||
import java.util.Random;
|
||||
|
||||
public class MatrixGenerator {
|
||||
public static double[][] generateMatrix(int rows, int cols) {
|
||||
double[][] matrix = new double[rows][cols];
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
matrix[i][j] = random.nextDouble() * 100; // Заполняем случайными числами
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
public class SingleThreadedMatrixProcessor {
|
||||
public static void process(double[][] matrix) {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
|
||||
// Вычисляем среднее арифметическое
|
||||
double sum = 0;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
sum += matrix[i][j];
|
||||
}
|
||||
}
|
||||
double average = sum / (rows * cols);
|
||||
|
||||
// Делим каждый элемент на среднее
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
matrix[i][j] /= average;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ThreadPoolMatrixProcessor {
|
||||
public static void process(double[][] matrix, int threadPoolSize) throws InterruptedException {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
|
||||
// Вычисляем среднее арифметическое
|
||||
double sum = 0;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
sum += matrix[i][j];
|
||||
}
|
||||
}
|
||||
double average = sum / (rows * cols);
|
||||
|
||||
// Создаем пул потоков
|
||||
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
|
||||
|
||||
// Обрабатываем каждую строку в отдельном потоке
|
||||
for (int i = 0; i < rows; i++) {
|
||||
final int row = i;
|
||||
executor.submit(() -> {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
matrix[row][j] /= average;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Завершаем работу пула
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(1, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
39
bartasova_ksenia_lab_1/readme.md
Normal file
39
bartasova_ksenia_lab_1/readme.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Лабораторная работа №1
|
||||
|
||||
Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания.
|
||||
Необходимо:
|
||||
1. Разработать однопоточный вариант алгоритма и замерить время его работы.
|
||||
2. Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы
|
||||
3. Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы.
|
||||
Массив генерируется до работы всех вариантов алгоритмов. Все три алгоритма обрабатывают три одинаковых массива.
|
||||
|
||||
## Вариант 3
|
||||
Разделить элементы матрицы на среднее арифметическое всех ее элементов.
|
||||
|
||||
### Как запустить лабораторную работу:
|
||||
javac Main.java компилирует исходный код
|
||||
java Main команда запускает скомпилированный класс
|
||||
|
||||
### Какие технологии использовали:
|
||||
java.util.concurrent используется для работы с многопоточностью и параллельными алгоритмами.
|
||||
- ExecutorService и Executors используются для управления пулами потоков и выполнения задач.
|
||||
- TimeUnit помогает работать с временными интервалами.
|
||||
- ForkJoinPool, RecursiveAction и RecursiveTask используются для параллельного выполнения задач, которые можно разбить на более мелкие подзадачи.
|
||||
|
||||
### Как работает программа:
|
||||
1. Генерируем матрицу размером 1000*1000
|
||||
2. Создаем три копии исходной матрицы
|
||||
3. Класс SingleThreadedMatrixProcessor обрабатывает матрицу в одном потоке
|
||||
4. Класс ThreadPoolMatrixProcessor обрабатывает матрицу с использованием пула потоков: создается пул потоков, каждая строка матрицы обрабатывается в отдельном потоке
|
||||
5. Класс ForkJoinMatrixProcessor обрабатывает матрицу с использованием ForkJoinPool и рекурсивного разделения задачи: если блок большой, он разделяется на две части, и каждая часть обрабатывается рекурсивно
|
||||
6. Выводятся результаты времени выполнения для каждого из трех подходов.
|
||||
### Тесты:
|
||||
Single-threaded: 0.015592711 сек
|
||||
ThreadPoolExecutor: 0.024355768 сек
|
||||
ForkJoinPool: 0.01131473 сек
|
||||
### Вывод:
|
||||
ForkJoinPool — самый быстрый. Однопоточный алгоритм — быстрее, чем ThreadPoolExecutor, но медленнее, чем ForkJoinPool. ThreadPoolExecutor — самый медленный в данном случае.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user