您的位置:首页 > 编程语言 > Java开发

Java并发29:ThreadLocalRandom学习笔记-随机数的三种使用方法

2018-03-25 22:32 344 查看
[超级链接:Java并发学习系列-绪论]

本章主要对ThreadLocalRandom进行学习。

1.ThreadLocalRandom简介

ThreadLocalRandom是Java提供的用于并发产生伪随机数的工具类,出现于JDK1.7版本中。

ThreadLocalRandom可以看做Math.random()并发升级类

ThreadLocalRandom不是直接用new实例化,而是第一次使用其静态方法current()

ThreadLocalRandom的优势类似于上章的ThreadLocal:每个线程单独一个变量副本,不再产生数据争用。

2.伪随机

所谓伪随机,即不是真正的随机:当使用同样的种子(seed)时,随机工具类会产生一样的随机数序列。

下面通过代码进行伪随机的学习:

分别进行两次随机数循环打印

两次随机数使用的种子相同

代码如下:

//获取种子
Long seed = System.currentTimeMillis();
/////////////////////////////// 伪随机 示例 ///////////////////////////////
System.out.println("================伪随机:种子相同,生成的随机数序列一致。");
random = new Random(seed);
System.out.println("第一次生成:");
for (int i = 0; i < 10; i++) {
System.out.print(random.nextInt() + " ");
}
random = new Random(seed);
System.out.println("\n重置种子\n第一次生成:");
for (int i = 0; i < 10; i++) {
System.out.print(random.nextInt() + " ");
}


运行结果:

================伪随机:种子相同,生成的随机数序列一致。
第一次生成:
382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302
重置种子
第一次生成:
382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302


从结果看,种子相同,生成的随机数序列一致,并不是真正的随机。

3.三种随机数实例

生成随机数有很多种方式,下面以三种方式进行练习:

Random:线程共享随机变量

ThreadLocalRandom:线程本地随机变量

ThreadLocal
<Random>
:线程本地随机变量

采取两种策略:

相同种子

不同种子

实例代码:

//java.util.Random 多线程-共享 伪随机 相同种子
System.out.println("================java.util.Random的多线程共享伪随机数");
//不同种子
System.out.println("----------------不同种子");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
random = new Random(System.currentTimeMillis());
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(random.nextInt() + " ");
}
System.out.println();
}).start();
}

Thread.sleep(100);
System.out.println("----------------相同种子-->证明Random的伪随机性");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
random = new Random(seed);
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(random.nextInt() + " ");
}
System.out.println();
}).start();
}

Thread.sleep(1000);
//java.util.concurrent.ThreadLocalRandom 多线程-并发 伪随机
System.out.println("\n================java.util.concurrent.ThreadLocalRandom的多线程并发伪随机数");
//不同种子
System.out.println("----------------不同种子");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
threadLocalRandom = ThreadLocalRandom.current();
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(threadLocalRandom.nextInt() + " ");
}
System.out.println();
}).start();
}

Thread.sleep(100);
//相同种子-->证明Random的伪随机性
threadLocalRandom = ThreadLocalRandom.current();
System.out.println("----------------相同种子-->证明Random的伪随机性");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(threadLocalRandom.nextInt() + " ");
}
System.out.println();
}).start();
}

Thread.sleep(1000);
//java.util.concurrent.ThreadLocal<Random> 多线程-并发 伪随机
System.out.println("\n================java.util.concurrent.ThreadLocal<Random>的多线程并发伪随机数");
Thread.sleep(100);
//不同种子
System.out.println("----------------不同种子");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
tlRandom.set(new Random(System.currentTimeMillis()));
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(tlRandom.get().nextInt() + " ");
}
System.out.println();
}).start();
}

Thread.sleep(100);
//相同种子-->证明Random的伪随机性
System.out.println("----------------相同种子-->证明Random的伪随机性");
for (int i = 0; i < 2; i++) {
Thread.sleep(100);
new Thread(() -> {
tlRandom.set(new Random(seed));
System.out.print(Thread.currentThread().getName() + ":");
for (int j = 0; j < 10; j++) {
System.out.print(tlRandom.get().nextInt() + " ");
}
System.out.println();
}).start();
}


运行结果:

================java.util.Random的多线程共享伪随机数
----------------不同种子
Thread-0:1209719284 -543898451 599398397 -16150711 -378920972 1585446581 -488873971 -829205970 -938436680 -45641360
Thread-1:1269740112 -410865868 -1328723315 109456979 -234600411 -307908712 -642144215 1188318491 123033431 143423699
----------------相同种子-->证明Random的伪随机性
Thread-2:382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302
Thread-3:382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302

================java.util.concurrent.ThreadLocalRandom的多线程并发伪随机数
----------------不同种子
Thread-4:-1076900907 1413014134 61153437 -391967598 -1288519279 -1610817129 -1180393198 60726166 1036092966 -987557314
Thread-5:1839222654 -1020613466 1431620360 746873003 -436040442 -1615521969 -2094704589 -113489507 1594492864 -1186578140
----------------相同种子-->证明Random的伪随机性
Thread-6:-1667209487 -754252478 -672050859 1793377410 580216652 595758109 1042779594 1039129943 -125685422 -1698765474
Thread-7:-1667209487 -754252478 -672050859 1793377410 580216652 595758109 1042779594 1039129943 -125685422 -1698765474

================java.util.concurrent.ThreadLocal<Random>的多线程并发伪随机数
----------------不同种子
Thread-8:-413521001 545178108 306926326 1860102961 973724015 -317981950 -353356762 -1257712729 1551816344 88775054
Thread-9:-365812138 -1000988543 205972525 418161839 -2105253272 -1052065104 -365059589 -2076841504 1955039530 -862216129
----------------相同种子-->证明Random的伪随机性
Thread-10:382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302
Thread-11:382893898 101358198 2106535064 -1939200049 2065597289 383574374 25675075 1140022109 1563937615 -640309302
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息