Reputation: 490
Consider the service class below:-
//Singleton service
public class InquiryService{
private final ExecutorService es = Executors. newSingleThreadExecutor();
private final CustomerService cs = new CustomerServiceImpl();
public String process(){
//Asynchronous calls to get info from CustomerService
Future<String> result = es.submit(()->{return cs.getCustomer()});
//Query database
//Perform logic et all
String customerName = result.submit.get();
//continue processing.
}
}
Service class above has an ExecutorService
as field. If say, 100 concurrent requests on process
method, does remaining (100-1) requests need to wait for thread availability?
How to solve the request wait? One option I could think is, instantiate, use and shutdown ExecutorService
within process
method. However aren't thread pool is meant to be reused?
Another option would be run as new Thread(new FutureTask<>(() -> {return cs.getCustomer()}))
. Which one is correct way?
Updates:-
Based from comments and answers, the ExecutorService
meant to be reused and frequent new Thread
creation is expensive. Therefore another option is just run service call sequentially.
Upvotes: 2
Views: 650
Reputation: 4591
Your service is singleton
which means only one instance exists throughout the runtime of your application (If implemented right!). So, effectively you have one ExecutorService
handling a newFixedThreadPool(1)
.
does remaining (100-1) requests need to wait for thread availability?
Oh yes, all your 100-1 other requests has to wait since the first request is already executing in the thread present in the threadpool. Since the thread pool is of fixed size, it can never grow to handle other requests.
How to solve the request wait?
You need more threads in your threadpool to take up your task.
One option I could think is, instantiate, use and shutdown ExecutorService within process method
This is really a bad idea. The time taken to create and destroy Thread
is too much. More on this here. That is whole idea of using a ThreadPool
.
Another option would be run as new Thread(new FutureTask<>(() -> {return cs.getCustomer()}))
Constructing a new Thread()
. Read my previous point.
So, what is right!?
One way would be to a Executors.newFixedThreadPool(10)
, so that (90-10) requests wait. Is it okay? Or maybe you are looking for newCachedThreadPool
!
Warning: Also, please read about side-effects of using ThreadLocal
in a ThreadPool
, if applicable.
Upvotes: 4