I have multiple threads which calculate the sum of a given array roughly speaking. I can't use separate worker threads and controller rather the whole program must be written in one class. The point of the program is to print the result of the calculation such that thread id 0 is the first to print the results, then thread id 1, then thread id 2, and so on in that order.
I wrote two synchronized methods in the class: finished
- notify all threads once a particular thread finished the calculation and waitForThread
- waits if threads with id's lesser than its own still haven't finished.
Because I can't use a separate controller class, I decided to create a static array doneArr
in which each cell symbolizes a thread id and once a thread finished its job it updates the corresponding cell in doneArr
. This way waitForThread
knows when to wait.
I can't seem to get this to work, can you please point me to the right direction?
EDIT: the problem can be easily solved by using join()
but I'm looking for a solution that uses synchronization.
This is the code:
public class WorkThread extends Thread {
private int[] vec;
private int id;
private int result;
private static int[] doneArr;
private static int progress = 0;
public WorkThread(int[] vec, int id) {
this.vec = vec;
this.id = id;
doneArr = new int[vec.length];
for(int i = 0; i < doneArr.length; i++) {
doneArr[i] = -1; //default value
}
}
private boolean finishedUpToMe() {
for(int i = 0; i < id; i++) {
if(doneArr[i] == -1)
return false;
}
return true;
}
private synchronized void waitForThread() throws InterruptedException {
while(!finishedUpToMe() && id > 0)
this.wait();
progress++;
}
private synchronized void finished() throws IllegalMonitorStateException {
this.notifyAll();
}
public int process(int[] vec, int id) {
int result = 0;
System.out.format("id = %d\n", this.id);
for(int i = 0; i < vec.length; i++) {
vec[i] = vec[i] + 1;
result = result + vec[i];
}
return result;
}
public void run() {
try {
this.waitForThread();
}catch (InterruptedException e) {
System.out.println("waitForThread exception");
}
result = process(vec, id);
doneArr[id] = id;
System.out.format("id = %d, result = %d\n", id, result);
try{
this.finished();
}catch (IllegalMonitorStateException e) {
System.out.format("finished exception\n");
}
}
public static void main(String[] args) {
int[] vec = {1,2,3,4};
WorkThread[] workers = new WorkThread[3];
for(int i = 0; i < workers.length; i++) {
workers[i] = new WorkThread(vec, i);
}
for(int i = 0; i < workers.length; i++) {
workers[i].start();
}
System.out.format("main\n");
}
}