Duvida com Threads

Olá Pessoal,
Estou estudando para tirar o OCJP e estou com uma dúvida quanto a thread abaixo, vou por o código e explico:

class Calculator extends Thread {
	int total;

	public void run() {
		synchronized (this) {
			
			for (int i = 0; i < 100; i++) {
				total += i;
			}
			notifyAll();
		}
	}
}


class Reader extends Thread {
	Calculator c;

	public Reader(Calculator calc) {
		c = calc;

	}

	public void run() {
		synchronized (c) {
			
				System.out.println("Waiting for calculation...");
				
				try {
					c.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
			System.out.println("Total is: " + c.total);
		}
	}

	public static void main(String[] args) {
		Calculator calculator = new Calculator();
		new Reader(calculator).start();
		new Reader(calculator).start();
		new Reader(calculator).start();
		calculator.start();
	}
}

Este código funciona bem somente se a Thread new Reader(calculator).start iniciar antes da calculator.start(). Caso a calculator.start() inicie antes então o c.wait() da Reader não recebe o notifyAll() da Calculator pois esta ja executou. Como resultado a soma não será impressa na tela, como é possível corrigir este código??

Agradeço a atenção

Sim, realmente o programa nao irá parar c o “notifyAll()” de Calculator executar antes de qualquer “wait()” de Reader…

então para diminuir essa possibilidade vc poderia criar um atributo estatico em Calculator para contar

quantos metodos “wait()” já foram executados, e quando igualar 3 ele deixa executar o “notifyAll()” com

uma chance de quase 100%, eu diria, para dar certo.

ficaria assim:

class Calculator extends Thread {
	int total;
	static int estado;

	public void run() {
		synchronized (this) {

			for (int i = 0; i < 100; i++) {
				total += i;
			}

			notifyAll();
		}
	}
}

public class Reader extends Thread {
	Calculator c;

	public Reader(Calculator calc) {
		c = calc;

	}

	public void run() {
		synchronized (c) {

			System.out.println("Waiting for calculation...");

			try {
				Calculator.estado++;
				c.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("Total is: " + c.total);
		}
	}

	public static void main(String[] args) {
		Calculator calculator = new Calculator();

		Reader r1 = new Reader(calculator);
		Reader r2 = new Reader(calculator);
		Reader r3 = new Reader(calculator);
		r1.setName("1");
		r2.setName("2");
		r3.setName("3");
		r1.start();
		r2.start();
		r3.start();

		while (Calculator.estado < 3) {

		}

		calculator.start();
	}
}