我使用的是一个OAuth库,它调用new Random().nextLong()来生成随机数,但是它会在异步调用中生成相同的随机数。我已经将其范围缩小到线程化Random.nextLong(),以每隔一段时间返回完全相同的数字。
有没有人知道这是不是Java的一个已知限制?如果是这样,有没有人知道线程安全操作?
编辑:我使用的是Java 1.6
编辑:这是我制作的一个小程序,用来测试我的大型应用程序中发生了什么。我运行了几次,而且更经常的是,当时间相同时,它会得到相同的随机数。请原谅我的快速编程。
public class ThreadedRandom {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadedRandom().run();
}
private RandomNumberGenerator _generator;
public ThreadedRandom()
{
_generator = new RandomNumberGenerator();
}
public void run()
{
Runnable r = new Runnable() {
@Override public void run() {
System.out.println(System.currentTimeMillis()+"\t"+_generator.gen());
}
};
Thread t1, t2;
t1 = new Thread(r);
t2 = new Thread(r);
t1.start();
t2.start();
}
private class RandomNumberGenerator {
Random random;
public RandomNumberGenerator()
{
random = new Random();
}
public Long gen() {
return new Random().nextLong();
}
}}
发布于 2011-01-26 03:22:04
您可能不希望每次都创建Random的新实例。而是拥有一个全球的。
发布于 2011-01-26 03:27:28
随机数不是真正的随机数,它们是“伪随机”的,它们需要一个“种子”值。如果使用相同的种子,则将生成相同的伪随机值序列。
创建Random类的新实例时,您可以自己指定种子,也可以让系统为您选择一个种子。在Java中,默认种子是以毫秒为单位的当前系统时间,请参见:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random%28%29
如果在同一毫秒内创建随机对象,则它们将具有相同的值序列。
通常,您希望在所有不同的线程之间共享单个Random对象,以避免此类问题。
发布于 2011-01-26 03:29:22
虽然我对Random的底层实现不是很熟悉,但如果让我猜的话,我会想象调用new Random()委托给new Random(System.currentTimeMillis())。这为在不同时间实例化的随机数提供了合理不同的Random序列。
但是,由于您提到了异步调用,因此您的两个调用实际上可能是同时执行的。这意味着当线程调用库时,它们同时调用new Random()调用,随机数得到相同的种子,因此它们将产生相同的随机序列。
https://stackoverflow.com/questions/4797849
复制相似问题