voce pode aumentar o alcance dos numeros pra que fique + dificil repetir por ex:
int num = (int)(Math.random()*1000+1);
ou fazer operações entre dois randoms…
so o que vai ti garantir mesmo e tu jogar esses valores em um array ou alguma Collection , e verificar se ja existe ele, e so sair do while
quanto a Colletion tiver o numero de elementos que tu quer, ou o length no caso do array.
Se isso ainda não te atender sugiro que utiliza a classe Random.
Essa classe é a implementação do algoritimo do Dr. Donald Knuth,
The Art of Computer Programming, Volume 2, Section 3.2.1.
Resposta curta: utilize uma boa semente.
A semente é um número aleatório que serve para inicializar o gerador de números randômicos. Quanto mais aleatória a semente, melhor o gerador de números aleatórios será. Exemplo:
Random random = new Random(System.nanoTime());
for (int i = 0; i < 10; i++) {
System.out.println("valor: " + random.nextInt());
}
No exemplo acima o System.nanoTime() é a semente que estou utilizando, mas poderia qualquer outro long. Se não especificar nenhuma semente no construtor então a classe Random usará como semente o System.currentTimeMillis() por padrão. Outra opção é multiplicar por outra variável aleatória como a quantidade de memória livre na máquina (Runtime.getRuntime().freeMemory() * System.currentTimeMillis() );