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 ...
随机推荐
- 回溯算法_01背包问题_Java实现
原文地址:http://blog.csdn.net/ljmingcom304/article/details/50314839 本文出自:[梁敬明的博客] 1.回溯算法 回溯算法也叫试探法,通俗的将就 ...
- svn add --no-ignore
提交新代码时:svn add --no-ignore /dir 不加的话可能会漏提交某些依赖或文件. Svn st -q --no-ignore. 提交时不需要加
- MGR Switch Muti-Primary to single_primary
MGR Muti-Primary 切换 single_primary 模式 原因:因为希望做ProxySQL+MGR之间Proxy层的消耗测试,需要把原有的MGR多主改为单主模式. 修改MGRgrou ...
- 设计模式之笔记--享元模式(Flyweight)
享元模式(Flyweight) 定义 享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象. 类图 描述 Flyweight:抽象享元类,是所有的具体享元类的基类,为子类规定出需要实 ...
- HTTP 请求 的方法Util
HTTP请求 的一系列方法总结 /** * *******************************传统请求--开始************************************** ...
- [ python ] 软件开发规范
在python开发中,我们建议采用如下规范: soft/ ├── bin # 程序执行文件目录 │ ├── __init__.py │ └── start.py # 程序开始执行脚本文件 ├─ ...
- [ python ] 字符串的操作及作业题
字符串的操作方法 capitalize() : 首字母大写 s1 = 'my heart will go on' print(s1.capitalize()) # 首字母大写 # 执行结果: # My ...
- Linux打补丁的一些问题
linuxpatchlinux内核文档commandheader类unix操作系统有一个很有趣的特性就是源代码级的补丁包.在windows上我们打补丁都是运行一个可执行的程序,然后就可以把补丁打完了, ...
- ntp 校时程序
//effect:send ntp packet and get the ntp packet ,make the time OK//2014.7.31 is OK//#include <sys ...
- beego学习笔记(2)
BEEGO的几个特点: 简单化 RESTful 支持.MVC 模型,可以使用 bee 工具快速地开发应用,包括监控代码修改进行热编译.自动化测试代码以及自动化打包部署. 智能化 支持智能路由.智能监控 ...