From bdc964c882b6fd1bee747406f4cbd2301b9b3acf Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 26 Mar 2024 18:13:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96ThreadUtil.safeSleep=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E7=94=A8System.nanoTime()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/hutool/core/thread/ThreadUtil.java | 16 ++++++---------- .../hutool/core/thread/ThreadUtilTest.java | 9 +++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/thread/ThreadUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/thread/ThreadUtil.java index facf19ff0..356573018 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/thread/ThreadUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/thread/ThreadUtil.java @@ -490,7 +490,7 @@ public class ThreadUtil { /** * 考虑{@link Thread#sleep(long)}方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数 * - * @param millis 给定的sleep时间 + * @param millis 给定的sleep时间(毫秒) * @return 被中断返回false,否则true * @see ThreadUtil#sleep(Number) * @since 5.3.2 @@ -498,18 +498,14 @@ public class ThreadUtil { public static boolean safeSleep(final long millis) { long done = 0; long before; - long spendTime; - while (done >= 0 && done < millis) { - before = System.currentTimeMillis(); + // 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/org/dromara/hutool/core/thread/ThreadUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/thread/ThreadUtilTest.java index ba72a9398..ebaefe6fd 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/thread/ThreadUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/thread/ThreadUtilTest.java @@ -101,4 +101,13 @@ public class ThreadUtilTest { }, "线程 - " + x).start(); } } + + @Test + void safeSleepTest() { + final long sleepMillis = RandomUtil.randomLong(1, 1000); + // 随机sleep时长,确保sleep时间足够 + final long l = System.currentTimeMillis(); + ThreadUtil.safeSleep(sleepMillis); + Assertions.assertTrue(System.currentTimeMillis() - l >= sleepMillis); + } }