Reputation: 25
i have a some data processing that i'm executing in a servlet called "myServlet" (for example), some times i receive a lot of data to process at the same time , i mean at the same time exaclty, i need a way to tell the client that the server is busy .
i tried to initialise an attribute in the ServletContext to false when the app starts, and then when ever i receive a request i check if the attribute is false, if it's the case i change it to true then i process, this way the next request will be droped as long as i'm processing. again this is not working well when i receive several requests at the same time, server process them all at the same time , i think that the some requests escape even before i change the ctx attribute to TRUE .... i think that i'm missing something
that's way i'm wondering if there is way to check if there is a data processing already, so that i stop at that point and send the server busy response to the client
hope that you guys got the idea (the problem)
thanks in advance ...
Upvotes: 2
Views: 576
Reputation: 6414
You can use ReentrantLock
(instead of boolean in the context, hold this lock in context or somewhere - it should be same instance across all the requests to this servlet), you need also to synchronize the locking operation to be sure that you return busy to anyone who will do request in the time when server is already busy, read the api and examples for this class, basic idea would be:
public class SomeService {
private final ReentrantLock lock = new ReentrantLock(); // or store it in context based on your needs
// ...
/** this method refuse to process if there is already ongoing processing */
public void heavyProcessing() {
synchronized (lock) {
if (lock.isLocked()) {
// return busy status here
return;
}
lock.lock(); // acquire the lock - here we have the winner request that will be processed
}
try {
// ... do the processing here
} finally {
lock.unlock()
}
}
}
It is all because "Out Of Order Execution". ReentrantLock is thread safe, but Boolean
or boolean
is not. Also you need synchornization (the synchronized
block) to ensure that you tell the proper status to the reuqest that come during ongoing processing.
BECAUSE:
Without proper synchronization beetween Threads there is no guarantee that the porgram is executed in the exact order it is written (the optimisation mechanisms can change order of execution if it would not affect single threaded program). To prevent such OOE optimisation you need to specify some synchronization points. ReenterantLock
is designed with this in mind, boolean
is not. The use of ReenterantLock
just puts such synchronization points into the executed code, so you gain the proper synchronization.
The synchronization beetween threads in java is very broad topic, I can't teach you here how to do it. One of good books about this subject is "Java Concurrency in Practice". I suggest reading this book first then asking here if something will be confusing to you.
Upvotes: 1