更新时间:
#Java Random、ThreadLocalRandom、UUID
- Random:产生一个伪随机数(通过相同的种子,产生的随机数是相同的
Random r=new Random();
System.out.println(r.nextBoolean());
System.out.print(r.nextInt(50));//随机生成0~50的随机数,不包括50
System.out.println(r.nextInt(20)+30);//随机生成30~50的随机数,不包括50
public static int getRandomNumber(int scale)
{
Random random = new Random();return random.nextInt(scale);
}
值得赞许的是,他没有直接在线程的run方法中直接使用代码,而是抽取出来作为一个接口公用,也许别处还能重用这份代码。但是在线程中使用时却发现,同一时刻,不同的线程获取到的伪随机数总是一样的,这与需求的要求不符。只有这么两行代码,函数也是可以重入的,问题出在哪里呢?
Random的实现是,在生成random实例的时候,会有一个伪随机种子,这个种子在实例创建的时候就生成了,也可以指定种子来创建实例。如果没有指定种子,则使用时间作为种子,时间的单位是纳秒,按道理来说两个时间完全撞在一起的概率也非常低了,但是实际上,在纳秒级别,时钟精度是有误差的,达不到这个精确度,因此会出现两个线程中的random实例使用了同一个种子,这样取第一个nextInt的时候也就是同一个值了。这也就是多个线程取得同一个值的原因。
- ThreadLocalRandom:是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。ThreadLocalRandom不是直接用new实例化,而是第一次使用其静态方法current()。
从Math.random()改变到ThreadLocalRandom有如下好处:
我们不再有从多个线程访问同一个随机数生成器实例的争夺。
取代以前每个随机变量实例化一个随机数生成器实例,我们可以每个线程实例化一个
ThreadLocalRandom t=ThreadLocalRandom.current();
System.out.println(t.nextInt(50));//随机生成0~50的随机数,不包括50
System.out.println(t.nextInt(30, 50));//随机生成30~50的随机数,不包括50
- UUID: UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库建立时的名称重复问题。目前最广泛应用的 UUID,即是微软的 Microsoft's Globally Unique Identifiers (GUIDs),而其他重要的应用,则有 Linux ext2/ext3 档案系统、LUKS 加密分割区、GNOME、KDE、Mac OS X 等等。
String u=UUID.randomUUID().toString();