Таймауты отладки в 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 только во время точек останова? Я хочу, чтобы отладка вела себя как обычное выполнение, включая таймауты, поэтому я не уверен, как это сделать в целом.

Похоже, это должно быть полезно. stackoverflow.com/a/39399216/3655191

Ran 18.06.2018 21:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
1 109
2

Ответы 2

Ссылка, прокомментированная Побежал, дала мне правильное представление: Запустите поток, который постоянно проверяет, достаточно ли долго спал 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
  • отключить "приостановить"

Теперь в режиме отладки он изменит ExecutionTime, чтобы isExpired всегда возвращал false.

Другие вопросы по теме