java 随机数种子
引子:需要实现每天随机获得一个礼包,且全服玩家随出来的都是同一个。
实现方案:以当前时间是一年的第几天作为random的种子,取1~礼包总个数范围内的随机值。
public static int getBuffId() {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.nanoTime());
int dateInYear = c.get(Calendar.DAY_OF_YEAR);
return new Random(dateInYear).nextInt() + ;
}
于是决定深入了解一下随机数的种子。
Random两种构造方法。一种是无参构造函数。种子是 ++seedUniquifier + System.nanoTime(), 所以每新new一个Random实例,种子都会变。
private static volatile long seedUniquifier = 8682522807148012L;
public Random() { this(++seedUniquifier + System.nanoTime()); }
另一种是设置种子的构造方法。
public Random(long seed) {
this.seed = new AtomicLong(0L);
setSeed(seed);
}
看一下next()方法。每次调用next()方法。种子就会发生变化 nextseed = (oldseed * multiplier + addend) & mask;
private final static long multiplier = 0x5DEECE66DL;
private final static long addend = 0xBL;
private final static long mask = (1L << ) - ;
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));//保证oldseed跟nextseed不相同
return (int)(nextseed >>> ( - bits));
}
public int nextInt() {
return next();
}
实例:
//实例1
Random random = new Random();
for (int i = ; i < ; i++) {
System.out.println(random.nextInt());
} System.out.println("..........."); //实例2
for (int j = ; j < ; j++) {
System.out.println(new Random().nextInt());
}
运行结果:
- -
...........
-
-
-
-
分析:运行结果不一样。原因如下:
实例1设定了种子1000,for循环里,nextSeed一直在变,所以随出来的值也每次不一样。
实例2每次new一个新的Random对象,每次seed都会被重置成1000,后面调用nextInt() 算出来的nextSeed都是同一个值,所以不管循环几次,随出来的结果都一样。
java 随机数种子的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- JAVA生成随机数种子的方法
Java里面有一个随机函数——Random,刚开始只是知道这个函数具有随机取值的作用,于是上网搜索了资料一番,做了一下一些关于Random函数的总结: Java中存在着两种Random函数: 一. ...
- java.uti.Random类nextInt方法中随机数种子为47的奇怪问题
一,问题描述 需要生成一个[0,1]的随机数.即随机生成 0 或者 1.使用java.util.Random类的 nextInt(int)方法,当构造Random类的对象并提供随机数种子时,发现了一个 ...
- [Java 安全]加密算法
Base64编码 算法简述 定义 Base64内容传送编码是一种以任意8位字节序列组合的描述形式,这种形式不易被人直接识别. Base64是一种很常见的编码规范,其作用是将二进制序列转换为人类可读的A ...
- 编写高质量代码:改善Java程序的151个建议(第2章:基本类型___建议26~30)
建议26:提防包装类型的null值 我们知道Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中.而在Java5中泛型更是 ...
- 随机数是骗人的,.Net、Java、C为我作证(转)
几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生成一个数,我们事先也不知道它生成什么数.比如在.Net中编写下面的代码: Random rand = ne ...
- Java中有四种常见的Map实现方法
在 HTML5 之前我们做图片预览主流做法有两种,第一种是通过 Flash 插件来做预览,第二种是 Ajax 实现的假预览,也就是说选择图片文件后,图片其实已经异步上传到服务器,服务器处理后返回图片路 ...
- 随机数是骗人的,.Net、Java、C为我作证
几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生成一个数,我们事先也不知道它生成什么数.比如在.Net中编写下面的代码: Random rand = ne ...
- [改善Java代码]不要随便设置随机种子
建议30: 不要随便设置随机种子 随机数在太多的地方使用了,比如加密.混淆数据等,我们使用随机数是期望获得一个唯一的.不可仿造的数字,以避免产生相同的业务数据造成混乱.在Java项目中通常是通过Mat ...
随机推荐
- ASLR pe 分析
ASLR 转:http://www.cnblogs.com/dliv3/p/6411814.html 3ks @author:dlive 微软从windows vista/windows server ...
- malloc原理和内存碎片【转】
转自:http://www.cnblogs.com/zhaoyl/p/3820852.html 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查 ...
- Linux-Load Average解析(转)
load Average 1.1:什么是Load?什么是Load Average? Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measur ...
- juery中循环遍历json数组
var dataList=[]; var stock0={stockcode:"007758",stockname:"商业政7",state:"1&q ...
- springMVC中ajax的实现
function addDebtResult(){ var repayIds=$("#repayIds").val(); var lateFeeDay=$("#repay ...
- Ubuntu 下查看已安装的软件
Ubuntu 下如何查看已安装的软件 1.查看安装的所有软件 dpkg -l 例如: dpkg -l | grep ftp 2.查看软件安装的路径 dpkg -L | grep ftp 也可以用 wh ...
- 查找网页元素对应的js代码
按F12打开调试窗口,切换到Sources选项卡,最右边的Event Listener Breakpoints里勾选Mouse下的mouseover即可,当鼠标移动到图片上时触发mouseover事件 ...
- EF – 7.一对多关联
5.6.8 <一对多关联(上)> 5.6.9 <一对多关联(下)> 一对多的关联,可以说是整个数据库应用程序中最常见的一种关联类型了,因此,必须高度重视这种关联类型CRUD的实 ...
- day4 使用yield实现单线程
一.yield生成器(yield) yield用来结束while循环,并且能够保持之前循环的状态,下一次调用的时候直接从yield开始执行,执行yield后面的程序,并且重新进行循环:另外,yield ...
- 爱奇艺全国高校算法大赛初赛C
区间$dp$. 倒着考虑这件事件,肯定有最后一个取走的数字,假设是$a[k]$,那么最后一次取走的价值肯定是$a[0]*a[k]*a[n+1]$,之前取走的价值和为$[1,k-1]$的价值加上$[k+ ...