I am developing an API. This API needs to do 2 DB queries to get the result.
I tried following strategies:
Created 2 threads in Service (use Callable and CoundownLatch) to run 2 queries parallel and detect finishing time.
public class PetService {
public Object getData() {
CountDownLatch latch = new CountDownLatch(2);
AsyncQueryDBTask<Integer> firstQuery= new AsyncQueryDBTask<>(latch);
AsyncQueryDBTask<Integer> secondQuery= new AsyncQueryDBTask<>(latch);
latch.await();
}
public class AsyncQueryDBTask<T> implements Callable {
private CountDownLatch latch;
public AsyncQueryDBTask(CountDownLatch latch) { this.latch = latch;}
@Override
public T call() throws Exception {
//Run query
latch.countDown();
}
It worked fine but I feel that I am breaking the structure of Spring somewhere.
I wonder what is the most efficient way to get data in Spring 4.
-How to know both of 2 threads that run own query completed their job?
-How to control thread resource such as use and release thread?
Thanks in advance.
You generally don't want to create your own threads in an ApplicationServer nor manage thread lifecycles. In application servers, you can submit tasks to an ExecutorService
to pool background worker threads.
Conveniently, Spring has the @Async
annotation that handles all of that for you. In your example, you would create 2 async methods that return a Future :
public class PetService {
public Object getData() {
Future<Integer> futureFirstResult = runFirstQuery();
Future<Integer> futureSecondResult = runSecondQuery();
Integer firstResult = futureFirstResult.get();
Integer secondResult = futureSecondResult.get();
}
@Async
public Future<Integer> runFirstQuery() {
//do query
return new AsyncResult<>(result);
}
@Async
public Future<Integer> runSecondQuery() {
//do query
return new AsyncResult<>(result);
}
}
As long as you configure a ThreadPoolTaskExecutor
and enable async methods, Spring will handle submitting the tasks for you.
NOTE: The get()
method blocks the current thread until a result is returned by the worker thread but doesn't block other worker threads. It's generally advisable to put a timeout to prevent blocking forever.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With