在Java中生成随机数的快速高效方法

Ank*_*kit 2 java random

我正在编写一个生成大量随机数的多线程Java程序.

其他详细信息: 这些数字用于创建0-99的随机数列表,不重复,并且列表中存在0-99范围内的每个数字(换句话说,列表包含0范围内的100个唯一元素-99).

生成随机数[事情已经尝试过!]

  1. 我有一个0-100的数字列表.我生成一个随机数,并将其用作索引,用于从中弹出一个元素ArrayList.
  2. 我用过Collections.shuffle().

以下是方法1的代码:

ArrayList<Integer> arr = new ArrayList<Integer>(); 
for (int i = 0; i < N; i++){
 arr.add(i, i);
}

for(int i=0; i<N; i++){
  int indx = rand.nextInt(arr.size());
  res.add(arr.get(indx));
  arr.remove(indx);
}
Run Code Online (Sandbox Code Playgroud)

对于第二种方法,我用第二个for循环替换了Collections.shuffle(arr).

由于生成随机数列表是我算法中最昂贵的部分,我想优化它.这让我想到了一些问题:

  1. 生成随机数的最快方法是什么?
  2. 如上所述,生成随机数列表的最快方法是什么?

PS:

  1. 我发现Collections.shuffle()比第一种方法慢
  2. 有人建议我使用rngd从Unix硬件生成随机数.有人曾尝试过这个吗?你是怎样做的?

Tom*_*icz 7

我认为问题Collections.shuffle()是使用默认Random实例,这是一个线程安全的单例.你说你的程序是多线程的,所以我可以想象同步Random是一个瓶颈.

如果您在Java 7上运行愉快,只需使用即可ThreadLocalRandom.仔细看,有一个版本明确地shuffle()采取Random实例:

Collections.shuffle(arr, threadLocalRandom);
Run Code Online (Sandbox Code Playgroud)

哪里threadLocalRandom只创建一次.

在Java 6上,您只需为Random每个线程创建一个单个实例.请注意Random,除非每次都可以提供随机种子,否则不应为每次运行创建新实例.