Java ThreadLocalRandom无法生成指定范围内目标值问题求助
循环无法终止的问题排查
代码示例
Long indx = getComboIndex(drawPosCombo,numsize,picksize); //[计算结果为1046] Long cycles = 0l; Long comboSize = getComboSize(numsize,picksize); //[计算结果为10626] Long testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); while(testIndex != indx){ testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); cycles += 1; }
问题描述
期望这段代码循环至testIndex与indx匹配后继续执行,但程序始终无法退出循环。加入cycles变量统计尝试次数,结果尝试210亿次后,仍未在(0,10626)范围内匹配到目标值1046,调试显示生成的随机数确实在指定范围内,十分困惑。
核心问题分析
你遇到的是Java包装类的典型陷阱:Long类型的!=运算符比较的是对象引用,而非数值本身。
Java对Long类型在-128~127范围内的数值有缓存池,这个区间内的包装类对象会复用,所以用==/!=能正确比较数值;但超出这个范围后,每次创建Long对象都会生成新的内存实例,即使数值相同,对象引用也不同。你的目标值1046远大于127,所以即使testIndex生成了1046,testIndex != indx的判断始终为true,循环永远无法终止。
解决方案
推荐三种修复方式,任选其一即可:
- 使用
equals()方法比较数值
while(!testIndex.equals(indx)){ testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); cycles += 1; }
- 拆箱为基本类型
long后比较
while(testIndex.longValue() != indx.longValue()){ testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); cycles += 1; }
- 直接使用基本类型
long声明变量(最彻底的方式,从根源避免包装类问题)
long indx = getComboIndex(drawPosCombo,numsize,picksize); //[计算结果为1046] long cycles = 0l; long comboSize = getComboSize(numsize,picksize); //[计算结果为10626] long testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); while(testIndex != indx){ testIndex = ThreadLocalRandom.current().nextLong(0, comboSize); cycles += 1; }
内容的提问来源于stack exchange,提问作者Roger Browne
相关产品推荐
相关产品推荐

