随机通过ThreadLocalRandom

37 java random multithreading

java.util.Random的实例是线程安全的.但是,跨线程并发使用相同的java.util.Random实例可能会遇到争用并因此导致性能不佳.请考虑在多线程设计中使用ThreadLocalRandom.

什么样的争论,从而表现不佳?有人可以,在这里解释一下吗?我不知道Random和ThreadLocalRandom里面有什么算法让它们变得不同.

Joh*_*0te 39

这可能有点帮助:

http://thoughtfuljava.blogspot.com/2012/09/prefer-threadlocalrandom-over-random.html


引自来源:

通常要生成随机数,我们要么创建一个java.util.Random或Math.random()的实例 - 它在第一次调用时在内部创建java.util.Random的实例.但是,在并发应用程序中,上述使用会导致争用问题

Random是线程安全的,可供多个线程使用.但是如果多个线程使用相同的Random实例,则多个线程共享同一个种子.它会导致多个线程之间的争用,从而导致性能下降.

ThreadLocalRandom是上述问题的解决方案.ThreadLocalRandom每个线程都有一个Random实例,可以防止争用.


因此,基本上,每个线程使用一个随机实例允许您停止同步所有线程必须使用的种子.

  • 如果我在每个线程中创建java.util.Random的新实例,是否会导致与在每个线程中使用ThreadLocalRandom相同的效果?还是java.util.Random的所有实例都使用相同的种子? (3认同)
  • "随机"问题的一部分是不必要的"同步"; 即使你创建一个每个线程,它也不会像`ThreadLocalRandom`那样高效. (3认同)

Tra*_*ers 7

ThreadLocalRandom 存在一些问题,您无法控制初始种子。我也没有在某处找到工作集种子方法。

应该注意的是,当多个线程使用 Math.random() 时存在争用,因为它们将在引擎盖下访问类 Random 的共享实例,因此使用 ThreadLocalRandom 也有一个替代方案,它也解决了种子问题。

ThreadLocalRandom 使用隐藏在线程中的种子。他们决定为你做最初的种子,没有任何办法控制它。您同样可以创建自己的 Random 实例并以线程本地方式使用它。因此,如果您执行以下操作:

/* my thread */
rnd = new Random(my_seed);
/* use rnd */
Run Code Online (Sandbox Code Playgroud)

您还将看到没有争用。使用相同的种子,您可以获得可重复的 随机序列,这有助于测试。当您有多个线程时,您可以在这些线程上分发种子。周围应该有算法来生成良好的距离种子。