diff --git a/hutool-core/src/main/java/cn/hutool/core/date/StopWatch.java b/hutool-core/src/main/java/cn/hutool/core/date/StopWatch.java index e83bd25de0..25d3cfcb57 100755 --- a/hutool-core/src/main/java/cn/hutool/core/date/StopWatch.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/StopWatch.java @@ -171,8 +171,9 @@ public class StopWatch { } final long lastTime = System.nanoTime() - this.startTimeNanos; - this.totalTimeNanos += lastTime; - this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime); + final long safeLastTime = Math.max(0, lastTime); + this.totalTimeNanos += safeLastTime; + this.lastTaskInfo = new TaskInfo(this.currentTaskName, safeLastTime); if (null != this.taskList) { this.taskList.add(this.lastTaskInfo); } diff --git a/hutool-core/src/test/java/cn/hutool/core/date/IssueIDFMXJTest.java b/hutool-core/src/test/java/cn/hutool/core/date/IssueIDFMXJTest.java new file mode 100644 index 0000000000..4c43d4ecba --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/date/IssueIDFMXJTest.java @@ -0,0 +1,29 @@ +package cn.hutool.core.date; + + + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; + +/** + * StopWatch 异常未释放资源问题测试(问题2) + */ +public class IssueIDFMXJTest { + @Test + void stopWatchNegativeTimeTest() throws NoSuchFieldException, IllegalAccessException { + final StopWatch stopWatch = new StopWatch(); + stopWatch.start("负耗时测试任务"); + + // 反射修改startTimeNanos为当前时间+1秒(模拟nanoTime回退) + final Field startTimeNanosField = StopWatch.class.getDeclaredField("startTimeNanos"); + startTimeNanosField.setAccessible(true); + startTimeNanosField.set(stopWatch, System.nanoTime() + 1_000_000_000); + + stopWatch.stop(); + + Assertions.assertEquals(0, stopWatch.getLastTaskTimeNanos()); + Assertions.assertEquals(0, stopWatch.getTotalTimeNanos()); + } +}