import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Semaphore; /** * @author Riste Stojanov */ public class Solution { static Semaphore barrier = new Semaphore(0); static Semaphore semaphore = new Semaphore(15); static List matrixQueue = new ArrayList<>(); static class FileScanner extends Thread { private static final List matrixFiles = new ArrayList<>(); private final File directoryToScan; FileScanner(File directoryToScan) { this.directoryToScan = directoryToScan; } @Override public void run() { try { List scanners = new ArrayList<>(); File[] files = directoryToScan.listFiles(); for (File file : files) { if (file.isFile() && file.getName().endsWith(".mat")) { synchronized (matrixFiles) { matrixFiles.add(file); } } if (file.isDirectory()) { FileScanner fs = new FileScanner(file); scanners.add(fs); fs.start(); } } for (FileScanner scanner : scanners) { scanner.join(); } System.out.println("Done scanning: " + directoryToScan.getAbsolutePath()); } catch (Exception e) { e.printStackTrace(); } } } static class Reader extends Thread { private final String matrixFile; int[][] matrix; Reader(String matrixFile) { this.matrixFile = matrixFile; } /** * This method should execute in background */ @Override public void run() { // todo: complete this method according to the text description // todo: The variable in should provide the readLine() method try (BufferedReader s = new BufferedReader(new FileReader(new File(matrixFile)))) { int n = Integer.parseInt(s.readLine().trim()); this.matrix = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { matrix[i][j] = Integer.parseInt(s.readLine().trim()); } } } catch (Exception e) { e.printStackTrace(); } } } static class Writer extends Thread { private final String outputPath; private final int[][] matrix; Writer(String outputPath, int[][] matrix) { this.outputPath = outputPath; this.matrix = matrix; } @Override public void run() { int n = matrix.length; try (BufferedWriter dos = new BufferedWriter(new FileWriter(outputPath))) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { // todo: write the element dos.write(""+matrix[i][j]); dos.write("\n"); } } } catch (Exception e) { e.printStackTrace(); } } } static class Transformer extends Thread { private final int[][] matrix; private final int row; private final int column; private int result; Transformer(int[][] matrix, int row, int column) { this.matrix = matrix; this.row = row; this.column = column; } @Override public void run() { try { // todo: allow maximum 15 parallel executions semaphore.acquire(); int n = matrix.length; for (int k = 0; k < n; k++) { result += matrix[row][k] * matrix[k][column]; } semaphore.release(); barrier.release(); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) throws FileNotFoundException, InterruptedException { List transformers = new ArrayList<>(); Reader reader = new Reader("data/m.mat"); // todo: execute file reading in background reader.start(); // todo: wait for the matrix to be read reader.join(); // todo: transform the matrix int n = reader.matrix.length; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { Transformer t = new Transformer(reader.matrix, i, j); transformers.add(t); // todo: start the background execution t.start(); } } // todo: wait for all transformers to finish barrier.acquire(n*n); int[][] result = new int[n][n]; for (Transformer t : transformers) { result[t.row][t.column] = t.result; } Writer writer = new Writer("data/out.txt", result); // todo: execute file writing in background writer.start(); FileScanner scanner = new FileScanner(new File("data")); // todo: execute file scanning in background scanner.start(); // todo: wait for the scanner to finish and show the results scanner.join(); for (File matrixFile : scanner.matrixFiles) { System.out.println(matrixFile.getAbsolutePath()); } } }