JDK随机数阻塞问题
2021-08-13 本文已影响0人
TinyThing
0x0 现象
最近开发中,线上环境偶尔会直接没响应,进入docker执行jstack发现,很多线程处于BLOCKED状态,导致服务无响应,如下所示:
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.security.provider.NativePRNG$RandomIO.implNextBytes(NativePRNG.java:543)
- waiting to lock <0x00000000f6253b28> (a java.lang.Object)
at sun.security.provider.NativePRNG$RandomIO.access$400(NativePRNG.java:331)
at sun.security.provider.NativePRNG$Blocking.engineNextBytes(NativePRNG.java:268)
at java.security.SecureRandom.nextBytes(SecureRandom.java:468)
at java.security.SecureRandom.next(SecureRandom.java:491)
at java.util.Random.nextInt(Random.java:390)
at com.cosmoplat.bapp.common.core.util.StringUtils.getStringRandom(StringUtils.java:550)
at com.cosmoplat.bapp.admin.controller.CompanyController.inviteCode(CompanyController.java:280)
百度后发现,是jdk8随机数的bug
解决方法
这里我们生成随机数使用了JDK中的SecureRandom.getInstanceStrong()
查看jdk源码注释,可以看到在SecureRandom上有
Note: Depending on the implementation, the generateSeed and
nextBytes methods may block as entropy is being gathered,
for example, if they need to read from /dev/random on various
Unix-like operating systems.
如果使用的实现类需要读取linux类系统中的/dev/random文件的话,那么nextBytes 是有可能阻塞的
从网上找的解决方案:
不采用SecureRandom.getInstanceStrong这个新方法,改成了SecureRandom.getInstance("NativePRNGNonBlocking")