Limit Java Method Execution Time

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

Предположим, вы хотите, чтобы метод Java работал не более пяти секунд и выдавал исключение, если превышается указанный временной интервал. Вот как вы можете это сделать с помощью jcabi-aspects и AspectJ:

Имейте в виду, что вы должны совмещать свои классы после компиляции, как объясняется здесь.

Давайте обсудим, как это на самом деле работает, но сначала я рекомендую вам прочитать этот пост, который объясняет, как аспекты AOP взаимодействуют с Java аннотациями.

Благодаря аннотации @Timeable и совмещению классов, каждый вызов метода load() перехватывается аспектом из jcabi-aspects. Этот аспект запускает новый поток, который мониторит выполнение метода каждую секунду, проверяя, выполняется ли он по-прежнему.

Если метод выполняется более пяти секунд, поток вызывает interrupt() для потока метода.

Несмотря на очень распространенное ожидание, что поток должен быть немедленно прерван при этом вызове, это совсем не происходит. Эта статья подробнее объясняет механизм. Давайте обсудим это кратко:

  1. Поток проверяет interrupted() так часто, как только может;

  2. Если маркер установлен, поток останавливается и выбрасывает InterruptedException

Этот метод не будет реагировать на вызов interrupt() и будет работать до тех пор, пока не будет завершена JVM (очень плохой дизайн).

Вот как мы должны перестроить его, чтобы он стал чувствительным к запросам на прерывание.

Другими словами, ваш метод может остановиться только сам по себе. Никто другой не может этого сделать. Поток, в котором он выполняется, не может быть завершен другим потоком. Лучшее, что может сделать другой поток, это отправить вашему потоку “сообщение” (через метод interrupt()), что пора остановиться. Если ваш поток игнорирует сообщение, никто не может ничего сделать.

Большинство операций ввода-вывода в JDK разработаны таким образом. Они проверяют статус прерывания своих потоков во время ожидания ресурсов ввода-вывода.

Таким образом, используйте аннотацию @Timeable, но имейте в виду, что могут возникнуть ситуации, когда поток нельзя прервать.

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-05 at 21:48

sixnines availability badge   GitHub stars