Problem description:
We have a given matrix randomly filled with digits and have to create separate threads for each row of the matrix that count how many times the digits encounter in that row.
Without these sleeps in the main thread, it's not working correctly..
Here's my solution.
Also it's following here:
public class TestingMatrixThreads {
public static void main(String[] arr) throws InterruptedException {
int[][] a = new int[67][6];
// class.Count works with class.Matrix, that's why I've made it this way
Matrix m = new Matrix(a);
m.start();
Thread.sleep(1000); // Here comes the BIG question -> how to avoid these
// manually created pauses
Count c;
Thread t;
// Creating new threads for each row of the matrix
for (int i = 0; i < Matrix.matr.length; i++) {
c = new Count(i);
t = new Thread(c);
t.start();
}
//Again - the same question
System.out.println("Main - Sleep!");
Thread.sleep(50);
System.out.println("\t\t\t\t\tMain - Alive!");
int sum = 0;
for (int i = 0; i < Count.encounters.length; i++) {
System.out.println(i + "->" + Count.encounters[i]);
sum += Count.encounters[i];
}
System.out.println("Total numbers of digits: " + sum);
}
}
class Count implements Runnable {
int row;
public static int[] encounters = new int[10]; // here I store the number of each digit's(array's index) encounters
public Count(int row) {
this.row = row;
}
public synchronized static void increment(int number) {
encounters[number]++;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ", searching in row " + row + " STARTED");
for (int col = 0; col < Matrix.matr[0].length; col++) {
increment(Matrix.matr[row][col]);
}
try {
Thread.sleep(1); // If it's missing threads are starting and stopping consequently
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + " stopped!");
}
}
class Matrix extends Thread {
static int[][] matr;
public Matrix(int[][] matr) {
Matrix.matr = matr;
}
@Override
public void run() {
//print();
fill();
System.out.println("matrix filled");
print();
}
public static void fill() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
matr[i][j] = (int) (Math.random() * 10);
}
}
}
public static void print() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
System.out.print(matr[i][j] + " ");
}
System.out.println();
}
}
}
P.S. I'm sorry if this question is too stupid for you to answer, but I'm a newbie in Java programming, as well as it's my very first post in stackoverflow, so please excuse me for the bad formatting, too :) Thank you in advance!
To answer your main question:
For example:
The
start
call, as you know, kicks off the otherThread
and runs theRunnable
. Thejoin
call then waits for that started thread to finish.A more advanced way to deal with multiple threads is with an
ExecutorService
. This detaches the threads themselves from the tasks they do. You can have a pool ofn
threads andm > n
tasks.Example:
Here we have 4 threads and 10 tasks.
If you go down this route you probably need to look into the
Future
API to so that you can check whether the tasks completed successfully. You can also return a value from the task; in your case aCallable<Integer>
would seem to be appropriate so that you can return the result of your calculation from thecall
method and gather up the results from theFuture
.