我正在开发一个API.此API需要执行2次DB查询才能获得结果.
我尝试了以下策略:
>在Controller中使用可调用作为返回类型.
>在Service中创建2个线程(使用Callable和CoundownLatch)并行运行2个查询并检测结束时间.
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();
}
它工作正常,但我觉得我正在破坏Spring的结构.
我想知道在Spring 4中获取数据的最有效方法是什么.
– 如何知道运行自己查询的2个线程完成了他们的工作?
– 如何控制线程资源,如使用和释放线程?
提前致谢.
解决方法:
您通常不希望在ApplicationServer中创建自己的线程,也不想管理线程生命周期.在应用程序服务器中,您可以将任务提交到ExecutorService以池化后台工作线程.
方便的是,Spring有@Async注释,可以为您处理所有这些.在您的示例中,您将创建两个返回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);
}
}
只要您配置ThreadPoolTaskExecutor并启用异步方法,Spring就会处理为您提交任务的过程.
注意:get()方法阻塞当前线程,直到工作线程返回结果,但不阻止其他工作线程.通常建议设置超时以防止永久阻塞.