Java 为什么模拟器不像我的设备那样随机?
我创建了一个小应用程序(作为一个项目,没有发布它的计划)。部分代码生成一个由随机数组成的网格,并使用所述数字列表中的精灵显示网格。至少在我的KindleFire(以及我试过的另一台设备)上,它的表现和预期的一样 然而,仿真器是另一回事。我认为模拟设备是一个通用的三星(4,也许)。同样的代码在模拟器上运行时,用一个精灵填充大约一半的网格,用另一个精灵填充一半的网格 在emulator上,网格可能如下所示:Java 为什么模拟器不像我的设备那样随机?,java,android,random,android-emulator,Java,Android,Random,Android Emulator,我创建了一个小应用程序(作为一个项目,没有发布它的计划)。部分代码生成一个由随机数组成的网格,并使用所述数字列表中的精灵显示网格。至少在我的KindleFire(以及我试过的另一台设备)上,它的表现和预期的一样 然而,仿真器是另一回事。我认为模拟设备是一个通用的三星(4,也许)。同样的代码在模拟器上运行时,用一个精灵填充大约一半的网格,用另一个精灵填充一半的网格 在emulator上,网格可能如下所示: 11177 11177 11777 11777 11777 而不是在真实设备上: 6425
11177
11177
11777
11777
11777
而不是在真实设备上:
64251
26253
87635
38415
28167
我的代码的相关部分(是的,我应该将new Random()
移到别处):
import java.util.Random;
// ... ... ...
对于(int i=0;i
我过去在Java中遇到过一些问题,Random
决定减少随机性(我相信这可能是由于优化)
为什么模拟器的行为不那么随机?(我该怎么解决呢?我怀疑你的“是的,我应该把new Random()
移到别处”这句话比你想象的更准确
您可以找到Android的java.util.Random类的源代码;注意,和版本是不同的
基特卡特:
public Random() {
// Note: Using identityHashCode() to be hermetic wrt subclasses.
setSeed(System.currentTimeMillis() + System.identityHashCode(this));
}
棉花糖:
public Random() {
// Note: Don't use identityHashCode(this) since that causes the monitor to
// get inflated when we synchronize.
setSeed(System.nanoTime() + seedBase);
++seedBase;
}
注意从毫秒粒度时间到纳秒粒度时间的变化。但是,只有当仿真设备实际具有粒度为的时钟时,此更改才相关。一些模拟器可能有非常粗糙的时钟,这意味着System.nanoTime()
可能会在一个相当快的循环的每次迭代中返回相同的值
您将在每个循环中创建新的随机数生成器,并使用N、N+1、N+2等对它们进行种子设定。因为种子几乎相同,所以第一个数字输出中的大多数位都相同
如果你把“新随机数”从循环中拉出来,它不仅会更有效率,还会让伪随机数生成器完成其完整序列,并提供更好的结果。@Laurel这是构造函数,而不是生成器的实现。“主”分支,它目前拥有即将发布的“N”版本的源代码,有一个非常不同的实现:@fadden它看起来像是Java已经使用了十多年的版本——一个48位LCG,其乘法器为0x5deec66dl,加法常数为0xBL。构造函数可能会以不同的方式设置种子,但所做的只是在LCG循环中选择一个入口点,从给定入口点生成的序列将是相同的。
public Random() {
// Note: Don't use identityHashCode(this) since that causes the monitor to
// get inflated when we synchronize.
setSeed(System.nanoTime() + seedBase);
++seedBase;
}