import java.lang.reflect.Array; import java.util.Random; import java.util.concurrent.CyclicBarrier; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; public class Main { static int SIZE = 4; int [][] a; int [][] b; int [][] c; int [][] d; CyclicBarrier barrier; ArrayList workingOn; public static void main(String[] args) { var main = new Main(); main.execute(); } void execute() { var random = new Random(); a = new int[SIZE][SIZE]; b = new int[SIZE][SIZE]; c = new int[SIZE][SIZE]; d = new int[SIZE][SIZE]; workingOn = new ArrayList<>(); workingOn.add(0); workingOn.add(0); for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { a[row][col] = random.nextInt(10); } } for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { b[row][col] = random.nextInt(10); } } printMatrix(a, "A"); printMatrix(b, "B"); for (int row = 0; row < SIZE; row++) { synchronized (workingOn) { workingOn.set(0, workingOn.get(0) + 1); System.out.println("Start thread " + row); new Thread(new Worker(row)).start(); } } while (workingOn.get(0) + workingOn.get(1) != 0) { synchronized (workingOn) { System.out.println("Checking threads." ); try { Thread.sleep(250); } catch (InterruptedException e) { } } } printMatrix(c, "C"); printMatrix(d, "D"); } static int computeAtPosition(int[][] m1, int[][] m2, int row, int col) { int product = 0; for (int k = 0; k < SIZE; k++) { product += m1[row][k] * m2[k][col]; } return product; } static void printMatrix(int[][] m1, String label) { System.out.println(label); for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { System.out.print("" + m1[i][j] + "\t"); } System.out.println(); } } class Worker implements Runnable { int row; public Worker(int row) { this.row = row; } public void run() { for (int col = 0; col < SIZE; col++) { c[row][col] = computeAtPosition(a, b, row, col); } System.out.println("Thread " + row + " done working on C."); synchronized (workingOn) { System.out.println("Thread " + row + " marked done working on C."); workingOn.set(0, workingOn.get(0) - 1); workingOn.set(1, workingOn.get(1) + 1); } for (int col = 0; col < SIZE; col++) { d[row][col] = computeAtPosition(c, a, row, col); } System.out.println("Thread " + row + " done working on D."); synchronized (workingOn) { System.out.println("Thread " + row + " marked done working on D."); workingOn.set(1, workingOn.get(1) - 1); } } } }