This is an AMP version of the article, its original content can be found here.
Limit Java Method Execution Time
Say, you want to allow a Java method to work for a maximum of five seconds and want an exception to be thrown if the timeframe is exceeded. Here is how you can do it with jcabi-aspects and AspectJ:
Keep in mind that you should weave your classes after compilation, as explained here.
Let's discuss how this actually works, but first, I recommend you read this post, which explains how AOP aspects work together with Java annotations.
annotation and class weaving, every call to a method
is intercepted by an aspect from jcabi-aspects.
That aspect starts a new thread that monitors the execution of a method
every second, checking whether it is still running.
If the method runs for over five seconds, the thread
on the method's thread.
Despite a very common expectation that a thread should be terminated immediately on that call, it is not happening at all. This article explains the mechanism in more detail. Let's discuss it briefly:
interrupt()sets a marker in a thread;
The thread checks
interrupted()as often as it can;
If the marker is set, the thread stops and throws
This method will not react to
interrupt() call and will work until JVM is killed (very bad design):
This is how we should refactor it in order to make sensitive to interruption requests:
In other words, your method can only stop itself. Nothing else can do it.
The thread it is running in can't be terminated by another thread. The best
thing that the other thread can do is to send your thread a "message"
interrupt() method) that it's time to stop. If your thread
ignores the message, nobody can do anything.
Most I/O operations in JDK are designed this way. They check the interruption status of their threads while waiting for I/O resources.
@Timeable annotation, but keep in mind that there could
be situations when a thread can't be interrupted.