在 Spring 4 中 运行 并行线程的优雅方式
Elegant way to run parallel threads in Spring 4
我正在开发 API。这个 API 需要做 2 次数据库查询才能得到结果。
我尝试了以下策略:
- 在 Controller 中使用可调用类型 return。
在服务中创建了 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 中获取数据的最有效方法是什么。
- 如何知道 运行 拥有查询的两个线程都完成了他们的工作?
-如何控制线程资源,如线程的使用和释放?
提前致谢。
您通常不想在 ApplicationServer 中创建自己的线程,也不想管理线程生命周期。在应用程序服务器中,您可以将任务提交到 ExecutorService
以汇集后台工作线程。
方便的是,Spring 有 @Async
注释可以为您处理所有这些。在您的示例中,您将创建 2 个 return 一个 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()
方法会阻塞当前线程,直到结果被工作线程return编辑,但不会阻塞其他工作线程。通常建议设置超时以防止永远阻塞。
我正在开发 API。这个 API 需要做 2 次数据库查询才能得到结果。
我尝试了以下策略:
- 在 Controller 中使用可调用类型 return。
在服务中创建了 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 中获取数据的最有效方法是什么。
- 如何知道 运行 拥有查询的两个线程都完成了他们的工作?
-如何控制线程资源,如线程的使用和释放?
提前致谢。
您通常不想在 ApplicationServer 中创建自己的线程,也不想管理线程生命周期。在应用程序服务器中,您可以将任务提交到 ExecutorService
以汇集后台工作线程。
方便的是,Spring 有 @Async
注释可以为您处理所有这些。在您的示例中,您将创建 2 个 return 一个 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()
方法会阻塞当前线程,直到结果被工作线程return编辑,但不会阻塞其他工作线程。通常建议设置超时以防止永远阻塞。