import java.io.*; import java.util.*; import java.util.concurrent.*; public class Main { public static int[][] generateMatrix(int rows, int cols) { int[][] matrix = new int[rows][cols]; Random random = new Random(); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] = random.nextInt(100); } } return matrix; } public static void writeMatrixToFile(int[][] matrix, String filename) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { for (int[] row : matrix) { for (int value : row) { writer.write(value + " "); } writer.newLine(); } } } public static int[][] readMatrixFromFile(String filename, int rows, int cols) throws IOException { int[][] matrix = new int[rows][cols]; try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { for (int i = 0; i < rows; i++) { String[] values = reader.readLine().trim().split(" "); for (int j = 0; j < cols; j++) { matrix[i][j] = Integer.parseInt(values[j]); } } } return matrix; } public static void singleThreadedSort(int[][] matrix) { int cols = matrix[0].length; int rows = matrix.length; int[] columnSums = new int[cols]; for (int j = 0; j < cols; j++) { for (int i = 0; i < rows; i++) { columnSums[j] += matrix[i][j]; } } sortColumns(matrix, columnSums); } public static void multiThreadedSortWithThreadPool(int[][] matrix, int numThreads) throws InterruptedException { int cols = matrix[0].length; int rows = matrix.length; ExecutorService executor = Executors.newFixedThreadPool(numThreads); int[] columnSums = new int[cols]; for (int j = 0; j < cols; j++) { final int col = j; executor.submit(() -> { for (int i = 0; i < rows; i++) { columnSums[col] += matrix[i][col]; } }); } executor.shutdown(); executor.awaitTermination(1, TimeUnit.MINUTES); sortColumns(matrix, columnSums); } public static void multiThreadedSortWithForkJoin(int[][] matrix) { int cols = matrix[0].length; int rows = matrix.length; int[] columnSums = new int[cols]; ForkJoinPool pool = new ForkJoinPool(); pool.invoke(new ColumnSumTask(matrix, columnSums, 0, cols - 1)); sortColumns(matrix, columnSums); } static class ColumnSumTask extends RecursiveAction { private final int[][] matrix; private final int[] columnSums; private final int start; private final int end; public ColumnSumTask(int[][] matrix, int[] columnSums, int start, int end) { this.matrix = matrix; this.columnSums = columnSums; this.start = start; this.end = end; } @Override protected void compute() { if (end - start <= 10) { for (int j = start; j <= end; j++) { for (int i = 0; i < matrix.length; i++) { columnSums[j] += matrix[i][j]; } } } else { int mid = (start + end) / 2; ColumnSumTask leftTask = new ColumnSumTask(matrix, columnSums, start, mid); ColumnSumTask rightTask = new ColumnSumTask(matrix, columnSums, mid + 1, end); invokeAll(leftTask, rightTask); } } } private static void sortColumns(int[][] matrix, int[] columnSums) { int cols = matrix[0].length; int rows = matrix.length; Integer[] columnIndices = new Integer[cols]; for (int j = 0; j < cols; j++) { columnIndices[j] = j; } Arrays.sort(columnIndices, Comparator.comparingInt(j -> columnSums[j])); int[][] sortedMatrix = new int[rows][cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { sortedMatrix[i][j] = matrix[i][columnIndices[j]]; } } for (int i = 0; i < rows; i++) { System.arraycopy(sortedMatrix[i], 0, matrix[i], 0, cols); } } public static void main(String[] args) throws IOException, InterruptedException { Scanner scanner = new Scanner(System.in); System.out.print("Input lines: "); int rows = scanner.nextInt(); System.out.print("Input columns: "); int cols = scanner.nextInt(); int[][] matrix = generateMatrix(rows, cols); writeMatrixToFile(matrix, "input_matrix.txt"); int[][] matrix1 = readMatrixFromFile("input_matrix.txt", rows, cols); int[][] matrix2 = readMatrixFromFile("input_matrix.txt", rows, cols); int[][] matrix3 = readMatrixFromFile("input_matrix.txt", rows, cols); long startTime = System.currentTimeMillis(); singleThreadedSort(matrix1); long endTime = System.currentTimeMillis(); System.out.println("One thread: " + (endTime - startTime) + " mc"); writeMatrixToFile(matrix1, "output_single_thread.txt"); startTime = System.currentTimeMillis(); multiThreadedSortWithThreadPool(matrix2, 4); endTime = System.currentTimeMillis(); System.out.println("ThreadPoolExecutor: " + (endTime - startTime) + " mc"); writeMatrixToFile(matrix2, "output_thread_pool.txt"); startTime = System.currentTimeMillis(); multiThreadedSortWithForkJoin(matrix3); endTime = System.currentTimeMillis(); System.out.println("ForkJoinPool: " + (endTime - startTime) + " mc"); writeMatrixToFile(matrix3, "output_fork_join.txt"); } }