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 ...
随机推荐
- KVC, KVO 实现原理
Key-Value Coding: 键值编码 (KVC) 方法调用: // 对象属性 // 类似: Person -> name setValue: forKey: // 对象的属性或者 属性的 ...
- Python中如何Debug
debug是编码是非常重要的调试技巧,通过在运行过程中设置断点,帮助开发人员更好的理解运行过程. Python中debug不像JAVA或者C++那样在IDE中设置断点那么直观. Python的debu ...
- 增加Android模拟器空间(Internal Storage)
转载 http://vase.iteye.com/blog/2114664 初学Android,发现模拟器上有不少限制,譬如标题中的存储限制,无论用ADT Manager如何设置,内部存储空间不会 ...
- C# 怎么显示中文格式的日期、星期几
//该语句显示的为英文格式DateTime.Now.DayOfWeek.ToString(); //显示中文格式星期几 "星期" + DateTime.Now.ToString(& ...
- Mybatis的初步使用
MyBatis 是当下最流行的持久层框架,也是ORM框架,本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google ...
- Hadoop(一):概述
一.Hadoop是什么? Hadoop是一个由Apache基金会所开发的分布式系统基础架构.Hadoop框架最核心的设计包含两个方面,一是分布式文件系统(Hadoop Distributed File ...
- C# 下载文件的四种方法
C# 文件下载四方法 - CSDN论坛 - CSDN.NET using System; using System.Data; using System.Configuration; using Sy ...
- 使用情况查询top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法. top - 01:06:48 up 1:22, 1 ...
- 查看压缩包内容tar -tf
linux 压缩文件内容查看 分类:Linux | 标签: linux 压缩文件内容查看 2012-03-14 22:01阅读(1243)评论(0) 1. zipinfo 执行zipinfo ...
- UTF-8和GB2312互转的最简单快捷的方法
一.如果你想把utf-8转为GB2312 1.用记事本打开源码,把<meta http-equiv="Content-Type" content="text/htm ...