[英]Debugging timeouts in IntelliJ IDEA
在我的應用程序中,如果不確定是否可以在合理的時間內滿足條件,我將使用超時退出某些無限循環。
為了計時,我使用系統的時間,因為它很簡單:
public class BenchmarkTimer
{
private long startTime;
public BenchmarkTimer()
{
startTime = System.currentTimeMillis();
}
public boolean isExpired(long milliseconds)
{
long executionTime = currentTimeMillis() - startTime;
return executionTime > milliseconds;
}
}
但是,在調試時,我不希望在凍結應用程序時繼續花費時間。 默認情況下,這顯然不起作用,因為即使在斷點期間,系統時間也將繼續。 我不想由於我在斷點上花費太長時間而無法繼續運行而導致超時,因為在正常的應用程序執行下,這種行為會有所不同(例如,在“放棄”之前將執行更多的嘗試)。
有什么解決辦法嗎? IntelliJ IDEA
可以僅在斷點期間暫停Java應用程序可見的系統時間嗎? 我希望調試的行為像包含超時的常規執行,所以我不確定一般如何完成此操作。
冉評論的鏈接給了我一個正確的主意:運行一個線程,該線程會不斷檢查Thread.sleep()
睡眠時間是否足夠短,否則事情會變得很糟糕,我們可能處於斷點,因此我們可以“確定”時間,再次請求系統時間時,返回較舊的時間。
import lombok.val;
import static com.mycompany.SystemTimeBreakpointFixer.getCurrentTimeMillis;
import static com.mycompany.SystemTimeBreakpointFixer.considerRunningTimerFixerThread;
import static java.lang.System.currentTimeMillis;
import static java.lang.management.ManagementFactory.getRuntimeMXBean;
public class BenchmarkTimer
{
private long startTime;
static
{
considerRunningTimerFixerThread();
}
public BenchmarkTimer()
{
startTime = getCurrentTimeMillis();
}
public boolean isExpired(long milliseconds)
{
val currentTimeMillis = getCurrentTimeMillis();
val executionTime = currentTimeMillis - startTime;
return executionTime > milliseconds;
}
static class SystemTimeBreakpointFixer
{
private static final String THREAD_NAME = "System Time Fixer";
private static final int CHECKING_DELAY = 100;
private static final int NON_BREAKPOINT_DELAY = 100;
private static final String DEBUGGING_INPUT_ARGUMENT = "-agentlib:jdwp";
private static final boolean ARE_WE_DEBUGGING;
static
{
ARE_WE_DEBUGGING = areWeDebugging();
}
private static boolean areWeDebugging()
{
val runtimeMXBean = getRuntimeMXBean();
val inputArguments = runtimeMXBean.getInputArguments();
val jvmArguments = inputArguments.toString();
return jvmArguments.contains(DEBUGGING_INPUT_ARGUMENT);
}
private static long totalPausedTime = 0;
private static Thread thread;
static long getCurrentTimeMillis()
{
sleepThread();
val currentTimeMillis = currentTimeMillis();
return currentTimeMillis - totalPausedTime;
}
static void considerRunningTimerFixerThread()
{
if (ARE_WE_DEBUGGING && thread == null)
{
startTimerFixerThread();
}
}
private static void startTimerFixerThread()
{
thread = new Thread(() ->
{
//noinspection InfiniteLoopStatement
while (true)
{
val currentMilliseconds = currentTimeMillis();
sleepThread();
val updatedMilliseconds = currentTimeMillis();
val currentPausedTime = updatedMilliseconds - currentMilliseconds - CHECKING_DELAY;
if (currentPausedTime > NON_BREAKPOINT_DELAY)
{
totalPausedTime += currentPausedTime;
}
}
});
thread.setName(THREAD_NAME);
thread.start();
}
private static void sleepThread()
{
try
{
Thread.sleep(CHECKING_DELAY);
} catch (InterruptedException exception)
{
exception.printStackTrace();
}
}
}
}
還稱贊到該文章的調試檢測。
在isExpired內部使用一個斷點,並在返回值中進行設置:
executionTime = 0
現在處於調試模式,它將修改執行時間,以便isExpired始終返回false
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.