生成并发随机数

Java Concurrency API 提供了一个特殊的类来在并发应用中生成伪随机数。它就是 ThreadLocalRandom 类 (Java 7 才有)。 它是线程局部变量。每个想生成随机数的线程有一个不同的生成器,但它们都由同一个类管理,对开发人员是透明的。 这种机制的性能好于使用一个共享的 Random 对象生成所有线程的随机数。

任务

使用 ThreadLocalRandom 类在一个并发应用中生成随机数。

实现

本节的示例代码在 com.elanzone.books.noteeg.chpt6.sect07 package中

  • Runnable 实现类 : TaskLocalRandom

    • 在构造函数中调用 ThreadLocalRandom.current() 方法初始化实际线程的随机数生成器
        public TaskLocalRandom() {
            ThreadLocalRandom.current();
        }
    
    • run() 方法: 使用 nextInt() 方法生成10个随机数,将线程名字和随机数输出到终端
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 10; i++) {
                System.out.printf("%s: %d\n", name, ThreadLocalRandom.current().nextInt(10));
            }
    
  • 控制类 : Main

    • 创建 3 个 TaskLocalRandom 对象及对应的线程,并启动
            Thread threads[] = new Thread[3];
    
            for (int i=0; i<3; i++) {
                TaskLocalRandom task = new TaskLocalRandom();
                threads[i] = new Thread(task);
                threads[i].start();
            }
    

讲解

本例的关键在于 TaskLocalRandom 类。在此类的构造函数中,调用了 ThreadLocalRandom 类的 current() 方法。 这个静态方法返回与当前线程关联的 ThreadLocalRandom 对象,这样就能用此对象生成随机数。 如果调用此方法的线程还没有 ThreadLocalRandom 对象与其关联,此类将创建一个。 本例中,在构造函数中使用此方法初始化与任务关联的随机数生成器,它将在下一次对此方法的调用时将被创建好。

在 TaskLocalRandom 类的 run() 方法中,调用 current() 方法获得关联此线程的随机数生成器。 调用 nextInt() 方法并传数字 10 作为参数,将返回一个在 0 和 10 之间的伪随机数。每个任务生成10个随机数。

了解更多

ThreadLocalRandom 类也提供方法来:

  • 生成 long、float、double 数字和 Boolean 值
  • 传递一个数字作为参数,生成值在 0 到该数字之间的随机数
  • 传递2个数字参数,生成在那2个数字之间的随机数