Duvida sobre programação paralela em Java

Estou começando a aprender programação paralela, e estou querendo comparar um programa com single thread com um com multi thread.

O que eu pensei foi fazer um algorítimo bem simples que, em um intervalo de 1 minuto, calculasse a quantidade maior de números primos possíveis, e, me mostrasse o último número primo calculado e a sua posição nos números primos, por exemplo, digamos que fosse o número 23, apareceria o numero 23 e sua posição, no caso 9, pois ele é o 9º número primo.

Sem utilizar o paralelismo, o número encontrado foi 774107, na posição 62039. Porém, ao utilizar paralelismo, eu obtive o número 1083757, na posição 84444 (posição errada, a certa seria 84547), acredito que tenha sido um erro bem básico, mas, como eu ainda não entendo muito de paralelismo, não consegui resolvê-lo.

Abaixo segue o código das duas classes que criei, a primeira, é a classe Calcula que só serve pra definir as instâncias e implementar o método run. A segunda é classe Principal.

Calcula:

import java.util.Collection;

public class Calcula extends Thread { 
  private int x;
  private int quantidade = 0;
  private int ultimo = 0;
  private long tempoInicial;

  public Calcula(int x, long tempoInicial) {
      this.x = x;
      this.tempoInicial = tempoInicial;
  }

  public int getQuantidade (){
      return quantidade;
  }

  public int getUltimo (){
      return ultimo;
  }

  @Override
  public void run() {
    long tempoMaximo=tempoInicial;
    while (tempoMaximo < tempoInicial+60000){
        tempoMaximo = System.currentTimeMillis();
        for(int z=2; z<x/2; z++){
            if (x%z==0) break;  
            else if(z==(x/2)-1){
                quantidade++;
                ultimo=x;
            }
        }
        x=x+8;
    }
  }

}

Principal:

import java.util.ArrayList;
import java.util.Collection;

public class Principal{
 public static void main(String[] args){
    long tempoInicial = System.currentTimeMillis();
    Calcula t1 = new Calcula (5, tempoInicial);
    Calcula t2 = new Calcula (7, tempoInicial);
    Calcula t3 = new Calcula (9, tempoInicial);
    Calcula t4 = new Calcula (11, tempoInicial);

    t1.start();
    t2.start();
    t3.start();
    t4.start();

    try{
        t1.join();
        t2.join();
        t3.join();
        t4.join();
    } catch (InterruptedException ex){
        ex.printStackTrace();
    }

    int ultimo = t1.getUltimo();
    if (ultimo < t2.getUltimo()) ultimo = t2.getUltimo();
    if (ultimo < t3.getUltimo()) ultimo = t3.getUltimo();
    if (ultimo < t4.getUltimo()) ultimo = t4.getUltimo();

    System.out.println("Último primo encontrado: " + ultimo);
    System.out.println("Quantidade de primos encontrados: " + (t1.getQuantidade() + t2.getQuantidade() + t3.getQuantidade() + t4.getQuantidade()));
 }
}

A lógica que eu segui foi começar cada thread com um valor diferente e ir implementando elas de 8 em 8, para que nenhuma calcule valores repetidos. No fim, pego o getQuatidade de cada e somo, e vejo o maior getUltimo para obter o maior valor. Acredito que o erro seja porque alguma thread esteja calculando um pouco mais rápido, então a quantidade sai errada.

Não entendi o que de paralelo tem no seu exemplo, ainda mais por você usar join em todas as threads. Você, apesar do problema de lógica que encontrou, está usando threads para fazer um processamento single thread. Será que esse é o melhor exemplo para lidar com threads?