diff --git a/CHANGELOG.md b/CHANGELOG.md index 3556c4f7f..111d4d68b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.27(2024-03-18) +# 5.8.27(2024-03-26) ### 🐣新特性 * 【extra 】 FreemarkerEngine修改默认版本参数 @@ -10,6 +10,7 @@ * 【core 】 HexUtil#format方法增加prefix参数(issue#I93PU9@Gitee) * 【core 】 StrUtil.replace歧义,修改为replaceByCodePoint(issue#I96LWH@Gitee) * 【core 】 FileUtil和PathUtil增加Resource重载(issue#I97FJT@Gitee) +* 【core 】 优化ThreadUtil.safeSleep,使用System.nanoTime()(issue#I9BMGK@Gitee) ### 🐞Bug修复 * 【core 】 修复PathMover对目标已存在且只读文件报错错误问题(issue#I95CLT@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java b/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java index 02dc882c1..2baafdf2a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java @@ -384,18 +384,14 @@ public class ThreadUtil { public static boolean safeSleep(long millis) { long done = 0; long before; - long spendTime; - while (done >= 0 && done < millis) { - before = System.currentTimeMillis(); - if (false == sleep(millis - done)) { + // done表示实际花费的时间,确保实际花费时间大于应该sleep的时间 + while (done < millis) { + before = System.nanoTime(); + if (!sleep(millis - done)) { return false; } - spendTime = System.currentTimeMillis() - before; - if (spendTime <= 0) { - // Sleep花费时间为0或者负数,说明系统时间被拨动 - break; - } - done += spendTime; + // done始终为正 + done += (System.nanoTime() - before) / 1_000_000; } return true; } diff --git a/hutool-core/src/test/java/cn/hutool/core/thread/ThreadUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/thread/ThreadUtilTest.java index e0e951baf..e793693ac 100644 --- a/hutool-core/src/test/java/cn/hutool/core/thread/ThreadUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/thread/ThreadUtilTest.java @@ -1,5 +1,6 @@ package cn.hutool.core.thread; +import cn.hutool.core.util.RandomUtil; import org.junit.Assert; import org.junit.Test; @@ -11,4 +12,13 @@ public class ThreadUtilTest { ThreadUtil.execute(() -> Assert.assertTrue(isValid)); } + + @Test + public void safeSleepTest() { + final long sleepMillis = RandomUtil.randomLong(1, 1000); + // 随机sleep时长,确保sleep时间足够 + final long l = System.currentTimeMillis(); + ThreadUtil.safeSleep(sleepMillis); + Assert.assertTrue(System.currentTimeMillis() - l >= sleepMillis); + } }