Have you tried this? Does it really happen? I have and yes it can, depending on how the random numbers were generated.
If so, there should be lots of ways to make each thread unique:
You might re-seed the randomizer with current time in millis right before you ask for a number. It's near impossible for all the threads to do this re-seed with the same time value. Actually new Random() does this anyway, will appallingly bad results here. It's extremely easy to create threads that get the same value of System.currentTimeMillis(), on my system at least.
Note that Math.random() works great here. That's because it's already been written to do what Leslie suggests: create a single static Random instance and keep re-using it for each new value. I'd use Math.random() if a double is desired; otherwise implement Leslie's solution for maximum customizability, to take advantage of the methods like nextLong(), nextInt(), etc. Alternately you can adapt the results of Math.random() with minor mathmatical transformations, but it's a bit less efficient than using Random's methods, and especially if you want a long, using Math.random() will probably do a poorer job of giving you an even random distribution than Random.nextLong() will. Roundoff errors will probably cause results to glob around certain values.
Maybe you could hash thread id and use it in the seed or multiply it into the random number. This could work - especially if thread contention (for the static random source) were an issue. I'd probably XOR the hash with the current time.
The main thread could pass a random number to each sub-thread, and the sub-thread could re-seed with that number. Also viable, if each thread is going to generate a lot of different numbers of its own.
or do all of the above! Urk.
That could be some ugly code...

[ July 23, 2003: Message edited by: Jim Yingst ]