I wanted to do make a program that allows to start x threads
and all threads are supposed to do a job:
counting average from Math.random() when number > 0.
I started doing it without volatile boolean
and it did not work.
But with volatile boolean it works as expected.
Could anyone explain me please why? Would it be possible to make it differently?
public class Worker extends Thread {
private int number;
private double average = 0;
private volatile boolean cancelled;
public Worker(int number) {
this.number = number;
cancelled = false;
}
public void run() {
while (!cancelled) {
if (number > 0) {
for (int i = 0; i < number; i++) {
average += Math.random();
if (number - 1 == i) {
average = average/this.number;
number = 0;
System.out.println(Thread.currentThread().getName() + " average is: " + average);
}
}
}
}
System.out.println(Thread.currentThread().getName() + " is cancelled...");
}
public void cancel() {
this.cancelled = true;
}
public double getAverage() {
return this.average;
}
public void setNumber(int number) {
this.number = number;
}
}
public class Executor {
private List<Worker> activeThreads;
private Double[] array;
public Executor(){
activeThreads = new ArrayList<>();
}
public void createThreads(int number, int count){
for(int i = 0; i < number; i++){
Worker worker = new Worker(count);
worker.setName("Thread " + i);
activeThreads.add(worker);
array = new Double[number];
worker.start();
}
}
public void cancelThreads(){
int count = 0;
for(Worker w : activeThreads){
w.cancel();
try {
array[count] = w.getAverage();
count++;
w.join();
} catch (InterruptedException ex) {
System.out.println("Interrupted exception");
Thread.currentThread().interrupt();
}
}
getFinalAverage();
}
public void startJob(int num){
activeThreads.forEach(t -> t.setNumber(num));
}
public void getActiveThreads(){
System.out.println(Thread.getAllStackTraces().keySet().size());
}
private void getFinalAverage(){
double finalAverage = 0;
for(Double d : Arrays.asList(array)){
finalAverage += d;
}
finalAverage = finalAverage / array.length;
System.out.println("Final average is " + finalAverage);
}
}