前言
ThreadLocalRandom和Random类都是 Java 中用于生成随机数的类,但它们有一些区别和不同的使用场景
竞争与性能
Random
Random类是线程安全的,可以在多个线程中共享使用- 但是,在多线程环境下,由于
Random类使用了同一个种子生成随机数序列,可能会导致竞争条件和性能问题- 竞争条件:如果多个线程同时使用同一个
Random对象并且种子相同,它们将竞争生成随机数序列的访问权。这可能导致多个线程同时尝试修改或读取随机数序列,从而导致竞争条件和不确定的结果 - 性能问题:当多个线程同时使用同一个
Random对象时,它们需要进行同步操作以确保线程安全。这涉及到锁定机制,会引入额外的开销和延迟,从而降低性能
- 竞争条件:如果多个线程同时使用同一个
ThreadLoacalRandom
ThreadLocalRandom类是 Java 7中引入的,它提供了一种更高效且线程安全的随机数生成方式- 每个线程都有自己的
ThreadLocalRandom实例,避免了多线程竞争问题,即避免多个线程同时访问同一个随机数生成器实例时的竞争,比使用同步机制的Random类在多线程环境下更高效 ThreadLocalRandom的高性能主要体现在以下几个方面:- 无锁设计:
ThreadLocalRandom使用了无锁设计,避免了多线程竞争的开销,提高了性能 - 基于线程的随机数生成器:每个线程都有自己的随机数生成器实例,避免了线程间的竞争,提高了并发性能
- 使用高效的算法:
ThreadLocalRandom使用了高效的随机数生成算法,例如 XorShift 算法,这些算法具有良好的性能和随机性 - 缓存数据:
ThreadLocalRandom在每个线程中缓存了一些随机数,减少了每次生成随机数时的开销
- 无锁设计:
使用方式
Random
- 通过创建
Random实例,然后调用其方法生成随机数
1 | Random random = new Random(); |
ThreadLoacalRandom
- 直接通过静态方法调用生成随机数
1 | int randomNumber = ThreadLocalRandom.current().nextInt(100); // 生成0到99之间的随机整数 |
总结
- 一般来说,如果在单线程环境中使用随机数,可以选择使用
Random类 - 而在多线程环境中,为了避免竞争条件和性能问题,建议使用
ThreadLocalRandom类