Reputation: 2550
I'm currently developing a web application using spring boot and I have a problem in the service layer.
I have a heavy method on my service layer. If multiple users call that same service, the applications stops due to low memory. So I want to limit the no of parallel running threads of that method only. So far I have come out with using synchronized on that method. But it will limit it to single threaded method.
@Service
public class DocumentService{
private synchronized void doReplacement(){
//should have limited no of multi threads (eg. 3)
}
private void normalMethod(){
//no restrictions
}
}
What can I do to achieve this task. Any help would be appreciated.
Upvotes: 3
Views: 7095
Reputation: 5369
You may be better of with using some sort of request throttling (i.e. number of requests per second) than with the number of threads that can execute a method simultaneously. For instance using Guava's RateLimiter directly, or maybe event adding declarative support for with Spring's AOP.
If you still want to go with threads, my suggestion would be to use an ExecutorService:
@Service
public class DocumentService {
private final ExecutorService executor;
@Autowired
public DocumentService(
@Value("${some.config.property}") int maxConcurrentThreads) {
// will allow only the given number of threads
executor = Executors.newFixedThreadPool(maxConcurrentThreads);
}
private void doReplacementWithLimitedConcurrency(String s, int i){
Future<?> future = executor.submit(() -> doReplacement(s, i));
future.get(); // will block until a thread picks up the task
// and finishes executing doReplacement
}
private void doReplacement(String s, int i){
}
// other methods
@PreDestroy
public void performThreadPoolCleanup() throws Exception {
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
executor.shutdownNow();
}
}
Upvotes: 2