Java:sonar代码审查问题总结 ----Random 问题
1,不规范代码 写在普通方法中,触发检查,在构造方法,成员属性声明中可以避开检查
Random random = new Random();
2,解决方案
方案一(使用次数不高的情况下推荐使用)
Random rand = new SecureRandom();
方案二(需要抛出或捕获NoSuchAlgorithmException异常,还有可能会造成阻塞 )
Random rand = SecureRandom.getInstanceStrong();
3,方案一二的 性能测试
当n=1 时
程序SecureRandom.getInstanceStrong()的nextInt()运行次数1运行时间: 130
程序new SecureRandom()的nextInt()运行次数1运行时间: 106
--------------
程序SecureRandom.getInstanceStrong()创建运行时间: 1
程序new SecureRandom()创建时间: 0
当n=10000时
程序SecureRandom.getInstanceStrong()的nextInt()运行次数10000运行时间: 139
程序new SecureRandom()的nextInt()运行次数10000运行时间: 202
当 n= 1000000时
程序SecureRandom.getInstanceStrong()的nextInt()运行次数1000000运行时间: 432
程序new SecureRandom()的nextInt()运行次数1000000运行时间: 832
public static void main(String[] args) throws NoSuchAlgorithmException {
// TODO Auto-generated method stub
/*
* 程序1运行时间: 239 程序2运行时间: 120
*/
int n =1;
long startTime = System.currentTimeMillis(); // 获取开始时间
Random rand2 = SecureRandom.getInstanceStrong();
for(int i =0;i<n;i++) {
rand2.nextInt();
}
long endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("--------------");
System.out.println("程序1运行次数"+n+"运行时间: " + (endTime - startTime) );
startTime = System.currentTimeMillis(); // 获取开始时间
Random rand = new SecureRandom();
for(int i =0;i<n;i++) {
rand.nextInt();
}
endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("程序2运行次数"+n+"运行时间: " + (endTime - startTime) );
startTime = System.currentTimeMillis(); // 获取开始时间
Random rand3 = SecureRandom.getInstanceStrong();
endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("--------------");
System.out.println("程序3运行次数"+n+"运行时间: " + (endTime - startTime) );
startTime = System.currentTimeMillis(); // 获取开始时间
Random rand4 = new SecureRandom();
endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("程序4运行次数"+n+"运行时间: " + (endTime - startTime) );
}
3,不符合规则原文
"Random" objects should be reused
4,原因
“Random”对象应该被重用,因为Random每次创建一个随机值时是低效的,而且根据JDK的不同,可能会产生非随机的数字。为了提高效率和随机性,创建一个单一的随机变量,然后存储和重用它。
Random()构造函数每次都尝试用不同的值设置种子。然而不能保证种子是随机的,甚至是均匀分布的。一些JDK将使用当前时间作为种子,这使得生成的数字根本不是随机的。
该规则发现在每次调用方法并将其分配给本地随机变量时创建一个新的随机变量的情况。
5文章参考
1,https://blog.csdn.net/u011519294/article/details/109227297
阻塞问题,看下方原文