我是一种在java中学习随机数生成和多线程的概念。
其想法是不要在特定毫秒内产生重复的随机数1000范围(考虑到,不超过50个数据,以多线程的方式将在毫秒内处理)。因此,在特定时间生成的随机数列表是唯一的。你能给我任何的想法吗,因为我在特定的毫秒内产生了几个重复的随机数(也有相当大的概率)。
我试过以下失败的地方。
Random random = new Random(System.nanoTime());
double randomNum = random.nextInt(999);//
int min=1; int max=999;
double randomId = (int)Math.abs(math.Random()* (max - min + 1) + min);//
Random random = new Random(System.nanoTime()); // also tried new Random();
double randomId = (int)Math.abs(random.nextDouble()* (max - min + 1) + min);当我附加正在生成的时间戳时,在多线程环境中,我看到为5000+唯一数据生成的is (大约8-10次)相同(2-4次)。
发布于 2013-10-01 09:04:56
这个类将允许您从某个范围获得非重复值,直到整个范围被使用为止。一旦使用了范围,它将被重新初始化。
类附带了一个简单的测试。
如果希望使类线程安全,只需将synchronized添加到nextInt()声明即可。
然后,您可以使用单例模式或仅使用一个静态变量从多个线程访问生成器。这样,所有线程都将使用相同的对象和相同的唯一id池。
public class NotRepeatingRandom {
int size;
int index;
List<Integer> vals;
Random gen = new Random();
public NotRepeatingRandom(int rangeMax) {
size = rangeMax;
index = rangeMax; // to force initial shuffle
vals = new ArrayList<Integer>(size);
fillBaseList();
}
private void fillBaseList() {
for (int a=0; a<size; a++) {
vals.add(a);
}
}
public int nextInt() {
if (index == vals.size()) {
Collections.shuffle(vals);
index = 0;
}
int val = vals.get(index);
index++;
return val;
}
public static void main(String[] args) {
NotRepeatingRandom gen = new NotRepeatingRandom(10);
for (int a=0; a<30; a++) {
System.out.println(gen.nextInt());
}
}
}发布于 2013-10-01 09:11:17
首先,您应该使用new Random(),因为它看起来像像这样 (细节取决于Java ):
public Random() { this(++seedUniquifier + System.nanoTime()); }
private static volatile long seedUniquifier = 8682522807148012L;也就是说,它已经使用了nanoTime(),并确保具有相同nanoTime()结果的不同线程获得不同的种子,而new Random(System.nanoTime())没有。
(编辑: Pyranja指出这是Java6中的一个bug,但它是固定的在Java 7中
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);)
第二,如果从1到1000生成50个随机数,那么由于生日悖论的存在,一些数字是相同的概率是相当高的。
第三,如果您只想要唯一的ids,可以使用AtomicInteger计数器而不是随机数。或者,如果您想要一个随机的部分开始,也附加一个计数器以及确保唯一性。
发布于 2013-10-01 09:16:12
如果我正确理解你的问题,多个线程同时创建自己的随机类实例,而所有线程都生成相同的随机数?生成相同的数目,因为所有在同一时间创建的随机实例,即具有相同种子的随机实例。
要解决这个问题,只需创建一个由所有线程共享的随机类实例,以便所有线程在同一个实例上调用nextDouble()。Random.nextDouble()类是线程安全的,它将使用每次调用隐式更新其种子。
//create only one Random instance, seed is based on current time
public static final Random generator= new Random();现在所有线程都应该使用相同的实例:
double random=generator.nextDouble() https://stackoverflow.com/questions/19111827
复制相似问题