Java ThreadLocalRandom产生重复随机数问题
为什么多线程产生一样的随机数?是写法错误吗?
另外,如果换成 Random实例,为什么就不一样了,不是说前者仅是后者的优化吗?
public class Task implements Runnable {
private static Random random = ThreadLocalRandom.current();
// private static Random random = new Random();
@Override
public void run() {
System.out.println(random.nextInt());
}
public static void main(String[] args) {
ExecutorService taskPool = Executors.newCachedThreadPool();
for(int n = 1; n < 10; n++) {
taskPool.submit(new Task());
}
taskPool.shutdown();
}
}
-1667209487
-1667209487
-1667209487
-1667209487
-1667209487
-1667209487
-1667209487
-1667209487
-1667209487
-1999664185
1468557546
183343793
770001684
1625714058
-2134889142
1456310974
-191722744
1763443594
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
每个线程都是15,30,14,这就是为啥是伪随机数
不好意思哦,我刚刚才看到你的问题。我感觉是你用错了可以查看(java1.8 api),里面已经很明确说明了绝对不可能跨多个线程共享一个
ThreadLocalRandom
, 还有我感觉@MageekChiu同学回答的也不对,没有根本上解决楼主的问题下面是我的代码希望能帮到你,最后想说正好我也在过java基础的东西,有兴趣的话可以看我的(gitHub),一起学习
这个不是多线程和的问题,是ThreadLocalRandom的问题,每个线程第n次随机数都一样。。。
这个问题我想通了,Random是以当前时间戳作为种子的,多线程下虽然线程安全但是会抢夺种子,使用种子并改变种子,而前者虽然也是当前时间作为种子但是不同的备份,也就是解释了多线程下会出现一致的问题,个人感觉设计有点过度了
看源代码:
localInit方法:
生成随机数时:
在主线程调用了 TreadLocalRandom 的 current() 方法,把主线程和主线程的 seed 存入了 UNSAFE。非主线程和 seed 的键值对之前并没有存入 UNSAFE。
所以直接ThreadLocalRandom.current().nextInt()去用。current()方法不会产生多个实例,放心用。