博客
关于我
剖析JDK源码-Random -(12)
阅读量:294 次
发布时间:2019-03-01

本文共 3627 字,大约阅读时间需要 12 分钟。

剖析JDK源码-Random -(12)

一、简述

该类的实例用于生成伪随机数。该类使用原值为48位的种子,其使用线性同余公式进行修改。如果使用相同的种子创建两个Random,并且对每个实例进行相同的方法调用该序列,则它们将生成并返回相同的数字序列。通过调用私有方法next(int bits)方法可以提供多达32个伪随机生成位。java.util.Random是线程安全的。 但是,跨线程的同时使用java.util.Random实例可能会遇到争用,从而导致性能下降。但java.util.Random并不是加密安全的。

二、类及常量的声明

public class Random implements java.io.Serializable {   	//使用JDK 1.1中的serialVersionUID实现互操作性 	static final long serialVersionUID = 3905348978240129619L; 	//与这个伪随机数生成器相关联的内部状态。 	private final AtomicLong seed;    private static final long multiplier = 0x5DEECE66DL;    private static final long addend = 0xBL;    private static final long mask = (1L << 48) - 1;    private static final double DOUBLE_UNIT = 0x1.0p-53; 	// 异常信息    static final String BadBound = "bound must be positive";    static final String BadRange = "bound must be greater than origin";    static final String BadSize  = "size must be non-negative";}

三、构造方法

  • 创建一个新的随机数生成器。 System.nanoTime()返回运行中的Java虚拟机的高分辨率时间源的当前值,以纳秒为单位。
  • 使用单个 long类型的参数创建一个新的随机数生成器。
public Random() {           this(seedUniquifier() ^ System.nanoTime());    }	 public Random(long seed) {           if (getClass() == Random.class)            this.seed = new AtomicLong(initialScramble(seed));        else {               this.seed = new AtomicLong();            setSeed(seed);        }    }

四、内部方法

  • 1、 public void nextBytes(byte[] bytes);生成随机字节并将它们放入用户提供的字节数组中。 产生的随机字节数等于字节数组的长度。
public void nextBytes(byte[] bytes) {           for (int i = 0, len = bytes.length; i < len; )            for (int rnd = nextInt(),                     n = Math.min(len - i, Integer.SIZE/Byte.SIZE);                 n-- > 0; rnd >>= Byte.SIZE)                bytes[i++] = (byte)rnd;    }
  • 2、返回下一个伪随机数,从这个随机数生成器的序列中均匀分布int值。 所有可能的int值以(大约)相等的概率产生。范围(0-232 )不包含232 获取指定值。
public int nextInt() {           return next(32);    }    public int nextInt(int bound) {           if (bound <= 0)            throw new IllegalArgumentException(BadBound);        int r = next(31);        int m = bound - 1;        if ((bound & m) == 0)  // i.e., bound is a power of 2            r = (int)((bound * (long)r) >> 31);        else {               for (int u = r;                 u - (r = u % bound) + m < 0;                 u = next(31))                ;        }        return r;}
  • 3、返回下一个伪随机数,从这个随机数发生器的序列中均匀分布long值。
    因为Random类使用只有48位的种子,所以该算法并不会返回所有可能的long值。
public long nextLong() {           // it's okay that the bottom word remains signed.        return ((long)(next(32)) << 32) + next(32);    }
  • 4、返回下一个伪随机数,从这个随机数发生器的序列中均匀分布boolean值。 值true和false以(大概)相等的概率产生。
public boolean nextBoolean() {           return next(1) != 0;    }
  • 5、这个随机数生成器的序列中返回下一个伪随机、均匀分布的浮点值在0.0到1.0之间。
public float nextFloat() {           return next(24) / ((float)(1 << 24));    }
  • 6、从这个随机数生成器的序列中返回下一个伪随机、均匀分布的双精度值在0.0到1.0之间。
public double nextDouble() {           return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;    }
  • 7、从该随机数发生器的序列返回下一个伪随机数,高斯(“正”)分布 double值,平均值为 0.0 ,标准差为 1.0 。
synchronized public double nextGaussian() {           // See Knuth, ACP, Section 3.4.1 Algorithm C.        if (haveNextNextGaussian) {               haveNextNextGaussian = false;            return nextNextGaussian;        } else {               double v1, v2, s;            do {                   v1 = 2 * nextDouble() - 1; // between -1 and 1                v2 = 2 * nextDouble() - 1; // between -1 and 1                s = v1 * v1 + v2 * v2;            } while (s >= 1 || s == 0);            double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);            nextNextGaussian = v2 * multiplier;            haveNextNextGaussian = true;            return v1 * multiplier;        }    }

转载地址:http://jhao.baihongyu.com/

你可能感兴趣的文章
mysql /*! 50100 ... */ 条件编译
查看>>
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>
mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
查看>>