简体   繁体   English

在不同的jvms或不同的机器上java中Math.random()的随机性如何

[英]how random is Math.random() in java across different jvms or different machines

I have a large distributed program across many different physical servers, each program spawns many threads, each thread use Math.random() in its operations to draw a piece from many common resource pools. 我有一个跨多个不同物理服务器的大型分布式程序,每个程序产生许多线程,每个线程在其操作中使用Math.random()从许多公共资源池中绘制一个片段。

The goal is to utilize the pools evenly across all operations. 目标是在所有操作中均匀地使用池。 Sometimes, it doesn't appear so random by looking at a snapshot on a resource pool to see which pieces it's getting at that instant (it might actually be, but it's hard to measure and find out for sure). 有时,通过查看资源池上的快照看它在那一瞬间得到哪些部分(实际上可能是这样,但很难测量并确定),它似乎并不是随机的。

Is there something that's better than Math.random() and performs just as good (not much worse at least)? 有没有比Math.random()更好的东西,并且表现得同样好(至少不是更差)?

Math.random() is based on java.util.Random , which is based on a linear congruential generator . Math.random()基于java.util.Random ,它基于线性同余生成器 That means its randomness is not perfect, but good enough for most tasks, and it sounds like it should be sufficient for your task. 这意味着它的随机性并不完美,但对于大多数任务来说已经足够好了,听起来它应该足以完成你的任务。

However, it sounds like you're using the double return value of Math.random() to choose between a fixed number of choices, which may further degrade the quality of the randomness. 但是,听起来你正在使用Math.random()double返回值来选择固定数量的选项,这可能会进一步降低随机性的质量。 It would be better to use java.util.Random.nextInt() - just be sure to reuse the same Random object. 最好使用java.util.Random.nextInt() - 只需确保重用相同的Random对象。

Sometimes, it doesn't appear so random by looking at a snapshot on a resource pool to see which pieces it's getting at that instant 有时,通过查看资源池上的快照来查看它在那一瞬间获得的部分,它看起来并不是那么随机

Our brains are really good at spotting patterns in perfect randomness, so that means almost nothing. 我们的大脑非常擅长以完美的随机性发现模式,因此几乎没有任何意义。

Math.Random's algorithm is "random enough" for any platform. Math.Random的算法对于任何平台来说都是“随机的”。 The mathematical model used for creating psuedo-random numbers is a good one. 用于创建伪随机数的数学模型是一个很好的模型。 It depends on how many threads you use. 这取决于您使用的线程数。 For anything but a really large number of threads, this will not give you even distribution (the nature of random numbers), and then Math.random() will give you plenty of overhead. 对于除了非常多的线程之外的任何东西,这都不会给你甚至分布(随机数的性质),然后Math.random()会给你足够的开销。

Try a better option: make a resource pool class, which distributes them evenly - and then just keep it's critical section in the "distribute" method protected. 尝试一个更好的选择:创建一个资源池类,它可以均匀地分配它们 - 然后只保留它在“distribute”方法中的关键部分受保护。

This thread can be usefull: How good is java.util.Random? 这个线程很有用: java.util.Random有多好?

another alternatives: 另一种选择:

  • generate a Random seed when init the random instance 在初始化随机实例时生成随机种子
  • if you using linux use /dev/urandom 如果你使用linux使用/ dev / urandom

Per the javadoc Math.random() is just an easy way of using java.util.Random. 根据javadoc,Math.random()只是一种使用java.util.Random的简单方法。 That said it's just a pseudo random algorythm. 这说它只是一个伪随机算法。 An easy way of checking how random an algorythm realy is, is by drawing random points on x/y grid. 检查algorythm的随机性的简单方法是在x / y网格上绘制随机点。 You should not find any patterns. 你不应该找到任何模式。

To get real ramdom numbers you can use services like http://www.random.org . 要获得真实的ramdom数字,您可以使用http://www.random.org等服务。 If this is to slow, maybe call it regularly to seed java.util.Random could get you closer to true random. 如果这样做很慢,可以定期调用它来播种java.util.Random可以让你更接近真随机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM