diff --git a/src/main/java/sbu/cs/MatrixMultiplication.java b/src/main/java/sbu/cs/MatrixMultiplication.java index 2f00c59..c67c9d9 100644 --- a/src/main/java/sbu/cs/MatrixMultiplication.java +++ b/src/main/java/sbu/cs/MatrixMultiplication.java @@ -1,5 +1,8 @@ package sbu.cs; +import javax.swing.plaf.TableHeaderUI; +import java.beans.PropertyEditorSupport; +import java.util.ArrayList; import java.util.List; public class MatrixMultiplication { @@ -8,19 +11,66 @@ public class MatrixMultiplication { public static class BlockMultiplier implements Runnable { List> tempMatrixProduct; - public BlockMultiplier() { + List> matrix_A; + List> matrix_B; + public BlockMultiplier(List> matrix_A, List> matrix_B) { //constructor // TODO + this.matrix_A = matrix_A; + this.matrix_B = matrix_B; } - @Override - public void run() { + public void run() { // the only task of threads is to multiplying those matrices /* TODO Perform the calculation and store the final values in tempMatrixProduct */ + tempMatrixProduct = multiplyingMatrix(matrix_A , matrix_B); } - } + public List> multiplyingMatrix(List> matrix_A, List> matrix_B) { //this method will multiply that two matrices which we pass it + int rows1 = matrix_A.size(); + int cols1 = matrix_A.get(0).size(); + int cols2 = matrix_B.get(0).size(); + + List> result = new ArrayList<>(); + for (int i = 0; i < rows1; i++) { + List row = new ArrayList<>(); + for (int j = 0; j < cols2; j++) { + int sum = 0; + for (int k = 0; k < cols1; k++) { + sum += matrix_A.get(i).get(k) * matrix_B.get(k).get(j); + } + row.add(sum); + } + result.add(row); + } + tempMatrixProduct = result; + return result; + } + } + // ---------------------------------- combining the four matrices(blocks) together ------------------------------------------ + public List> khodeMatrix (List> block1 , List> block2 , List> block3 , List> block4) { + // block 1 : up & left + // block 2 : up & right + // block 3 : down & left + // block 4 : down & right + // first we combine upper blocks then lower block with each other, then combine them to a final matrix + List> finalMatrix = new ArrayList<>(); + // combining block 1 & block 2 (upper blocks) + for (int i = 0 ; i < block1.size() ; i++) { + List row = new ArrayList<>(block1.get(i)); + row.addAll(block2.get(i)); + finalMatrix.add(row); + } + // combining block 3 & block 4 (lower blocks) + for (int i = 0 ; i < block3.size() ; i++) { + List row = new ArrayList<>(block3.get(i)); + row.addAll(block4.get(i)); + finalMatrix.add(row); + } + return finalMatrix; + } + // ---------------------------------- combining the four matrices(blocks) together ------------------------------------------ /* Matrix A is of the form p x q Matrix B is of the form q x r @@ -28,16 +78,132 @@ public void run() { */ public static List> ParallelizeMatMul(List> matrix_A, List> matrix_B) { - /* - TODO - Parallelize the matrix multiplication by dividing tasks between 4 threads. - Each thread should calculate one block of the final matrix product. Each block should be a quarter of the final matrix. - Combine the 4 resulting blocks to create the final matrix product and return it. - */ - return null; + List> temp1 = new ArrayList<>(); + List> temp2 = new ArrayList<>(); + List> temp3 = new ArrayList<>(); + List> temp4 = new ArrayList<>(); + + //----------------------------------------------for separating the matrix--------------------------------------------------- + + for (int i = 0; i < matrix_A.size()/2; i++) { // the upper part of the matrix ---> thread 1 + temp1.add(matrix_A.get(i)); + } + + for (int i = 0; i < matrix_B.size(); i++) { // the left part of the matrix ---> thread 2 + List row = new ArrayList<>(); + for (int j = 0; j < matrix_B.get(0).size()/2 ; j++) { + row.add(matrix_B.get(i).get(j)); + } + temp2.add(row); + } + + for (int i = matrix_A.size()/2 ; i < matrix_A.size(); i++) { // the down part of the matrix --->thread 3 + temp3.add(matrix_A.get(i)); + } + + for (int i = 0; i < matrix_B.size(); i++) { // the right part of the matrix ---> thread 4 + List row = new ArrayList<>(); + for (int j = matrix_B.get(0).size()/2 ; j < matrix_B.get(0).size() ; j++) { + row.add(matrix_B.get(i).get(j)); + } + temp4.add(row); + } + + // ----------------------------------------------for separating the matrix--------------------------------------------------- + + List listOfBlocks = new ArrayList<>(); + + BlockMultiplier blockMultiplier1 = new BlockMultiplier(temp1 , temp2); //up & left + listOfBlocks.add(blockMultiplier1); + + BlockMultiplier blockMultiplier2 = new BlockMultiplier(temp1 , temp4); //up & right + listOfBlocks.add(blockMultiplier2); + + BlockMultiplier blockMultiplier3 = new BlockMultiplier(temp3 , temp2); // down & left + listOfBlocks.add(blockMultiplier3); + + BlockMultiplier blockMultiplier4 = new BlockMultiplier(temp3 , temp4); //down & right + listOfBlocks.add(blockMultiplier4); + + // ------------------------------------------------------------------------------------------------------------------------- + + // ----------------------------------------------for starting the threads--------------------------------------------------- + + List listOfThreads = new ArrayList<>(); + for (BlockMultiplier blockMultiplier : listOfBlocks) { + Thread thread = new Thread(blockMultiplier); + listOfThreads.add(thread); + } + + for (Thread listOfThread : listOfThreads) { + listOfThread.start(); + } + + for (Thread thread : listOfThreads) { + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // ----------------------------------------------for starting the threads--------------------------------------------------- + // ------------------------------------------------------------------------------------------------------------------------- + // ---------------------------------- combining the four matrices(blocks) together ------------------------------------------ + + MatrixMultiplication matrixMultiplication = new MatrixMultiplication(); + + // ---------------------------------- combining the four matrices(blocks) together ------------------------------------------ + // ------------------------------------------------------------------------------------------------------------------------- + List> matrix = matrixMultiplication.khodeMatrix(blockMultiplier1.tempMatrixProduct , + blockMultiplier2.tempMatrixProduct , blockMultiplier3.tempMatrixProduct , blockMultiplier4.tempMatrixProduct); + return matrix; } public static void main(String[] args) { // Test your code here + List> matrix_A = new ArrayList<>(); + List> matrix_B = new ArrayList<>(); + List row1A = new ArrayList<>(); + row1A.add(1); + row1A.add(2); + row1A.add(3); + List row2A = new ArrayList<>(); + row2A.add(4); + row2A.add(5); + row2A.add(6); + List row3A = new ArrayList<>(); + row3A.add(7); + row3A.add(8); + row3A.add(9); + List row4A = new ArrayList<>(); + row4A.add(10); + row4A.add(11); + row4A.add(12); + matrix_A.add(row1A); + matrix_A.add(row2A); + matrix_A.add(row3A); + matrix_A.add(row4A); + List row1B = new ArrayList<>(); + row1B.add(13); + row1B.add(14); + List row2B = new ArrayList<>(); + row2B.add(17); + row2B.add(16); + List row3B = new ArrayList<>(); + row3B.add(17); + row3B.add(18); + matrix_B.add(row1B); + matrix_B.add(row2B); + matrix_B.add(row3B); + BlockMultiplier blockMultiplier = new BlockMultiplier(matrix_A , matrix_B); + List> result; + result = blockMultiplier.multiplyingMatrix(matrix_A , matrix_B); + for (List innerList : result) { + for (Integer element : innerList) { + System.out.print(element + " "); + } + System.out.println(); + } } } diff --git a/src/main/java/sbu/cs/TaskScheduler.java b/src/main/java/sbu/cs/TaskScheduler.java index 8725c2a..86cafc0 100644 --- a/src/main/java/sbu/cs/TaskScheduler.java +++ b/src/main/java/sbu/cs/TaskScheduler.java @@ -1,6 +1,10 @@ package sbu.cs; +import com.sun.source.tree.TryTree; + import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; public class TaskScheduler @@ -9,7 +13,7 @@ public static class Task implements Runnable { /* ------------------------- You don't need to modify this part of the code ------------------------- - */ + */ String taskName; int processingTime; @@ -17,23 +21,33 @@ public Task(String taskName, int processingTime) { this.taskName = taskName; this.processingTime = processingTime; } + public int getProcessingTime() { + return processingTime; + } /* ------------------------- You don't need to modify this part of the code ------------------------- - */ + */ @Override public void run() { + /* TODO Simulate utilizing CPU by sleeping the thread for the specified processingTime */ + + try{ + System.out.println(taskName + " is started "); + Thread.sleep(processingTime); + }catch(Exception e) { + System.out.println(e.getMessage()); + } } } - public static ArrayList doTasks(ArrayList tasks) - { + public static ArrayList doTasks(ArrayList tasks) throws InterruptedException { ArrayList finishedTasks = new ArrayList<>(); - + Collections.sort(tasks , Comparator.comparing(Task::getProcessingTime)); // for sorting the objects base on their processing time /* TODO Create a thread for each given task, And then start them based on which task has the highest priority @@ -41,11 +55,34 @@ public static ArrayList doTasks(ArrayList tasks) You have to wait for each task to get done and then start the next task. Don't forget to add each task's name to the finishedTasks after it's completely finished. */ - + Thread thread; + for (int i = 0 ; i < tasks.size() ; i++) { + thread = new Thread(tasks.get(i)); + thread.start(); + try { + thread.join(); + }catch (Exception e){ + e.printStackTrace(); + } + } + for (int i = tasks.size()-1 ; i >= 0 ; i--) { // coping the tasks array list in the finishedTasks array list + finishedTasks.add(tasks.get(i).taskName); + } return finishedTasks; } - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { // Test your code here + ArrayList tasks = new ArrayList<>(); + + tasks.add(new Task("A", 1000)); + tasks.add(new Task("B", 1200)); + tasks.add(new Task("C", 5000)); + tasks.add(new Task("E", 2000)); + tasks.add(new Task("F", 3000)); + + // for (int i = 0 ; i < tasks.size() ; i++ ) { + System.out.println(doTasks(tasks)); + // } } } diff --git a/src/main/java/sbu/cs/Theory-Questions.md b/src/main/java/sbu/cs/Theory-Questions.md new file mode 100644 index 0000000..cdde720 --- /dev/null +++ b/src/main/java/sbu/cs/Theory-Questions.md @@ -0,0 +1,76 @@ +### First Code : +``` + +public static class SleepThread extends Thread { + public void run() { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + System.out.println("Thread was interrupted!"); + } finally { + System.out.println("Thread will be finished here!!!"); + } + } + } + + public static void main(String[] args) { + SleepThread thread = new SleepThread(); + thread.start(); + thread.interrupt(); + } + +``` +### Output : +#### "Thread was interrupted!" +#### "Thread will be finished here!!!" + + +### Why : +#### in this provided code inside the main method we call the start method to start the threads, so it means the thread is trying to be run then we call the interrupt() method which will interrupt the function of the thread and it makes an exception, why ? because the thread is running then we interrupt its function so the output will be : "Thread was interrupted!" and then "Thread will be finished here!!!". +### Second Code : +``` +public class DirectRunnable implements Runnable { + public void run() { + System.out.println("Running in: " + Thread.currentThread().getName()); + } +} + +public class Main { + public static void main(String[] args) { + DirectRunnable runnable = new DirectRunnable(); + runnable.run(); + } +} +``` + +### Output : +#### Running in: main +### Why : +#### when we do not initialize a new Thread it will consider the default thread means main thread then the current thread will be main thread +### Third Code : +``` +public class JoinThread extends Thread { + public void run() { + System.out.println("Running in: " + Thread.currentThread().getName()); + } +} + +public class Main { + public static void main(String[] args) { + JoinThread thread = new JoinThread(); + thread.start(); + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Back to: " + Thread.currentThread().getName()); + } +} +``` +### Answer : +#### because the join() method causes this event : the calling thread to wait for the specified thread to be finished : +#### 1. we are taking an object from that class which will run the thread +#### 2. we call start() method for that thread +#### 3. then we are calling the join() method for that thread which is meaning this that the calling thread will wait for the specific thread to be ran and executed then it will continue which in this code the Mian thread will wait for the object thread to be executed then the Main thread will continue**** +