Your safest bet is using an applicaton wide thread pool with a max amount of threads, so that the tasks will be queued whenever necessary. The ExecutorService
is very helpful in this.
Upon application startup or servlet initialization use the Executors class:
executor =Executors.newFixedThreadPool(10);// Max 10 threads.
Then during servlet's service (you could ignore the result for the case that you aren't interested):
Future<ReturnType> result = executor.submit(newCallableTask());
Finally, during application's shutdown or servlet's destroy:
executor.shutdownNow();// Returns list of undone tasks, for the case that.