SecureRandom 缺点
SecureRandom在java各种组件中使用广泛,可以可靠的产生随机数,如生成 UUDID。
但在大量产生随机数的场景下,性能会较低。
原因如下:
public static UUID randomUUID() {
SecureRandom ng = Holder.numberGenerator;
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
生成uuid时用到ng.nextBytes()方法
ng.nextBytes()方法如下:
public void nextBytes(byte[] bytes) {
secureRandomSpi.engineNextBytes(bytes);
}
用到sun.security.provider.SecureRandom类的engineNextBytes()方法
进入该方法:
public synchronized void engineNextBytes(byte[] var1) {
}
该方法时同步的,所以在并发生成UUID时,效率会低下
解决
在linux系统中,启动java时,加下面参数:
-Djava.security.egd=file:/dev/./urandom
加快随机数产生过程
为什么有.
在这个bug的连接里有人反馈及时对 securerandom.source 设置为/dev/urandom它也仍然使用的/dev/random,有人提供了变通的解决方法,其中一个变通的做法是对securerandom.source设置为/dev/./urandom才行
linux中的/dev/urandom用于生成伪随机数,是非阻塞的,速度快
linux中的/dev/random是阻塞的,速度较慢
感谢:
https://blog.51cto.com/leo01/1795447
https://blog.csdn.net/F8qG7f9YD02Pe/article/details/89880266
https://www.cnblogs.com/softidea/p/5827467.html