看上面两段代码, 唯一的不一样是第二个 while 循环里面多了一个输出语句.
一开始我以为是编译器对此进行了优化, 只取了一次ac.getSecond, 而第二段代码没有被编译器进行优化, 所以能够顺利通过单元测试.
于是我添加了一个计数器, 统计这个 while 循环运行里多少次, 根据先前的推论, 计数器在这里编译器不得不执行这段程序, 杜绝了编译器层级优化的可能性, 但是, 令人疑惑的地方出现了, 会像第一种那样继续在死循环里, 所以这个思路不正确.
我又测试了 do...while 和 while (ture) 的写法, 结果也一样, 所以大概率不是编译器优化的原因.
上 Stack Overflow 找找原因, 找到了一个可能性是主线程的优先级高, 死循环占用了系统资源, 虽然不是非常令人信服, 但是可以试一试.
将输出改成了 Thread.sleep(50) 的确通过测试.
但是 Thread.sleep 过于丑陋, Sonarlint 的建议是使用 Awaitility, 果断走起.
修改后的语句如下 :
await
等待最多3秒, 结束条件是ac.getSecond()>=2, 要注意两点 :
- Sonarlint 的建议是使用 Duration.SECOND 似乎在 jdk 12 没有找到, 通过查看源代码, 这里使用了 TimeUnit.SECONDS
- until 那里传入一个 runnable, 果断 jdk 8 的 lambda 匿名函数走起来, oracle 万岁~