当前位置: 首页 > 知识库问答 >
问题:

从Java8开始编写'new Random()'有什么理由吗?

况浩邈
2023-03-14

出于某种原因,我曾经认为java.util.random是线程不安全的,a-lahashmapbitset,而math.random()是通过synchronized块包装对random的访问,或ThreadLocalRandom.Current().NextDouble()来实现的。

实际上,java.util.random是线程安全的(通过原子)。因此,需要注意的是:即使在单个线程中需要一些随机输入,使用ThreadLocalRandom也是有意义的,因为内部没有原子读写,没有被编译为锁定指令并发出内存障碍。

而且,由于Java8,ThreadLocalRandom本质上是一个单例,它的状态保留在Java.lang.Thread类的某些字段中。因此,方法ThreadLocalRandom.Current()不是对ThreadLocalMap的访问,而只是静态字段读取,即。e.非常便宜。

我有两个问题:

>

  • 从计算机科学的角度来看,多个线性同余随机生成器(以ThreadLocalRandom的方式初始化)的输出是否与单个线性同余随机生成器(java.util.random实例)的输出相同“随机”?

    如果第一个问题的答案是肯定的,那么是否有任何理由编写构造new Random()(没有种子)而不是ThreadLocalRandom.Current()

    更新。我认为像ThreadLocalRandom.Current().ints().Parallel().Collectron(...)这样的调用可能是不正确的,因为线程的随机生成器状态可能未在ForkJoinPool工作线程中初始化,但似乎ThreadLocalRandom重写了ints()Longs()Doubles()方法,从而使上述构造正确。

  • 共有1个答案

    乔凯康
    2023-03-14

    1...

    这取决于实现,但对于Java来说,它将是 <罢工> 相同 并不是那么糟糕,因为Java有一个静态的唯一种子原子long,每次创建一个Random时都会对其进行操作。然而,在其他语言或实现中,情况并非如此,它们可能只是使用系统时间(Java也使用系统时间,但结合使用唯一的种子),这一点我不会感到惊讶。也就是说,在某些系统中,您可以为多个线程获得相同的种子。

    经过进一步的检查和一些实际测试(尽管是脆弱的测试),我以前可能是错的,因为同时使用多个(我指的是100K个)随机数生成器实际上是更糟糕的(尽管它们是不同的实例)。我不完全确定它的种子冲突或者仅仅是实际的全局种子增量变得可预测的事实。当然,这可能只是我的测试工具或方法。

    所以从理论上讲,它应该更好,因为ThreadLocalRandom会创建独立的序列,所以也许我的测试有缺陷。

    这当然是基于伪随机的。

    物理随机性或基于实际熵的安全随机发生器可能会导致差异(即更多/更少的熵),但我不是专家,我没有机会访问一个。

    我无法提出一个特定的用例,但其中一个可能是,您使用一个ExecutorService来不断创建和处理线程(假设它们无法控制这些线程),但永远不会一次创建和处理多个线程(即最多2个并发线程)。您可能会发现ThreadLocalRandom的开销更大,而不是创建单个共享随机。

    另一个原因(给出您的注释后可能更好的原因)是,您可能希望为所有进程重置种子。如果您有一个使用线程的游戏(不是很多都使用线程,而是让我们假装),您可能需要全局重置种子以进行测试,这要比尝试将消息传递给所有正在运行的线程容易得多。

    您可能不想使用ThreadLocalRandom的另一个原因是平台原因。有些平台对线程创建有特定的要求,从而对线程本地创建有特定的要求。因此,为了解决“你有一个比Randoms更大的问题”,请查看谷歌应用程序:

    一个Java应用程序可以创建一个新线程,但是对于如何做有一些限制。这些线程不能“超过”创建它们的请求。(在后端服务器上,应用程序可以生成一个后台线程,该线程可以“活”过创建它的请求。)

    并针对您关于为什么要使用不能重用线程的ExecutorService的附加评论:

    或者将com.google.appengine.api.ThreadManager.CurrentRequestThreadFactory()返回的工厂对象与ExecutorService一起使用(例如,调用Executors.NewCachedThreadPool(factory))。

     类似资料:
    • 问题内容: 它应该与HTML4和XHTML向后兼容。约翰·雷西格(JohnResig)发表了一些好处。 只要我们不使用任何新功能且尚不支持的功能,就可以开始使用此doctype建立网站吗? 问题答案: 好考虑一下: 当用作text / html时,您需要的一个doctype就是触发标准模式。除此之外,对于浏览器而言,doctype不会执行任何操作。 当用作text / html时,无论您使用XHT

    • 我正在使用RecyclerView,我注意到一个奇怪的行为:每次被称为记录实际位置时,我都会放一个日志,有时位置不是从零开始的,你知道为什么吗?对我来说,这是一个问题,因为在位置0,我有不同的逻辑。 那是记录器: 好吧,我知道顺序并不总是一样的,但在我的应用程序中,当我更新数据时,我注意到两个ViewHolder的布局之间有一个神秘的交换,但在我的代码中,我从未为ViewHolder分配布局。正如

    • 问题内容: 我指的是模块中的OrderedDict,这是一个有序的字典。 如果它具有可订购的附加功能,我意识到这通常不是必需的,但是即使如此,是否还有缺点?慢一点吗?是否缺少任何功能?我没有看到任何丢失的方法。 简而言之,为什么我 不 总是使用它而不是普通的词典? 问题答案: 是的子类,并且需要更多内存来跟踪键的添加顺序。这不是小事。该实现在幕后增加了第二个,所有键的双向链接列表(这是记住顺序的部

    • 我读到这个关于Java的和之间的区别的问题,后者已经有几年的历史了。让我吃惊的是,只有一个问题提到了使用的任何缺点;也就是说,如果使用大量CPU,加速比就会降低。 假设您不在某种特殊的单线程环境中,是否应该始终选择?有什么理由不这样做吗?请注意,上面问题的一个答案提到,如果元素少于4096个,将直接调用。

    • 当写作《插件开发全攻略》系列文章的时候,我想首先罗列一些为什么WordPress 用户想要编写一个WordPress 插件的理由是有好处的。 下面罗列了为什么一个WordPress 用户应该考虑编写一个WordPress 插件的七个理由。 你喜欢一个插件的创意但是不喜欢这个插件的实现方式 无论是在Weblog Tools Collection 还是在官方的WordPress 插件目录或者WordP

    • 问题内容: Sun 用什么语言写? 问题答案: Sun实际上有多个JVM。所述热点JVM在C ++主要被写,因为热点在很大程度上基于所述Animorphic Smalltalk的VM被用C ++编写 。 比HotSpot更有趣的是IMHO Maxine Research VM ,它几乎完全用Java编写。