java - 在 Spring 4 中运行并行线程的优雅方式

标签 java spring multithreading nonblocking countdownlatch


我正在开发一个 API。此 API 需要执行 2 次数据库查询才能获得结果。
我尝试了以下策略:

  • 在 Controller 中使用 callable 作为返回类型。
  • 在服务中创建了 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 个返回 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);
    }
}

只要您配置一个ThreadPoolTask​​Executor 并启用异步方法,Spring 就会为您处理提交任务。

注意:get() 方法会阻塞当前线程,直到工作线程返回结果,但不会阻塞其他工作线程。通常建议设置超时以防止永远阻塞。

关于java - 在 Spring 4 中运行并行线程的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41971999/

相关文章:

c++ - 具有独立读取器和写入器线程的单个队列是否需要锁定?

c# - 返回Task的接口(interface)的同步实现

java - 内部也有 arraylist 的对象出现问题 : Arraylist of objects,

java - 运行此程序时出现无法访问的代码错误,但我不知道为什么

java - 如何获取 Spring Boot @Async 方法拒绝任务的详细信息?

java - 使用 Maven 运行 Spring boot 应用程序时出错 : Name for parameter binding must not be null

java - 多个线程修改相同的命令属性

java - 无配置java服务器有什么用处?

Java:检测给定字符编码的不可显示字符

java - spring roo windows安装 "Could not find or load main class"