Issue
I have a couple controller methods that must not be allowed to run at the same time:
@Scheduled(cron = "0 * * * * *")
public void first() {
// Acts on database
}
@RequestMapping(value = "/second", method = RequestMethod.POST)
public void second() {
// Also acts on same database
}
First one runs only as a scheduled job. Second one only runs as an HTTP request.
When second() gets called I want it to wait until first() finishes if it is running, then run immediately afterwards. If first() is not running, want second() to run and block first() from running while second() is still running. By block I mean don't allow first() to run at all, don't wait for second() to finish or queue it to run later either. It will attempt to run again only on its next scheduled run.
Edit: If second() gets requested again while the previous request to second() has not yet completed, want that new request to be ignored.
Solution
If you have to maintain this only on one instance of your application, then you can use for example AtomicBoolean
:
Let's create additional method, where you make something like this:
private AtomicBoolean isSecondRunning = new AtomicBoolean();
@Scheduled(cron = "0 * * * * *")
public void first() {
if (isSecondRunning.get()) {
return; // 1
}
execute();
}
@RequestMapping(value = "/second", method = RequestMethod.POST)
public void second() {
isSecondRunning.set(true); // 2
try {
execute();
} finally {
isRunning.set(false); // 3
}
}
public synchronized void execute(){
// here execute the code
}
Code explanation:
- if
isSecondRunning
is true, then return from first without execution, if is false, then skip if and go toexecute()
method - when second is executed, then set
isSecondRunning
to true and then execute - set
isSecondRunning
to false, and do it inside finally block, so we can be sure, that it is set to false even if some exception occurs in your execution
The execute
method is synchronized, so if first is running, then second will wait
Answered By - dey
Answer Checked By - Willingham (JavaFixing Volunteer)