单线程情况下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
局限性:
Random的局限性并不是线程安全的问题,而是在大量线程并发的时候,通过CAS机制更新随机数种子会导致大量线程自旋,耗费CPU性能,导致系统吞吐量下降。
源码
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException(BadBound);
//1.根据老的种子生成新的种子
int r = next(31);
//2.根据新的种子计算随机数
int m = bound - 1;
if ((bound & m) == 0) // i.e., bound is a power of 2
r = (int)((bound * (long)r) >> 31);
else {
for (int u = r;
u - (r = u % bound) + m < 0;
u = next(31))
;
}
return r;
}
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));//CAS,如果seed的值还是为oldseed,就用nextseed替换掉,并且返回true,退出while循环,如果已经不为oldseed了,就返回false,继续循环
return (int)(nextseed >>> (48 - bits));
}
多线程下ThreadLocalRandom用法:
ThreadLocalRandom t=ThreadLocalRandom.current();
System.out.println(t.nextInt(50));//随机生成0~50的随机数,不包括50
System.out.println(t.nextInt(30, 50));//随机生成30~50的随机数,不包括50
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomDemo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Player().start();
}
}
private static class Player extends Thread {
@Override
public void run() {
System.out.println(getName() + ": " + ThreadLocalRandom.current().nextInt(100));
}
}
}