简体   繁体   English

如何在不询问Future值的情况下使ExecutorService或CompletionService完成?

[英]How to get ExecutorService or CompletionService to finish without asking for values of Futures?

We have some work to be done within a thread which will be run on a server for a web app using Spring Boot . 我们需要在一个线程中完成一些工作,该线程将使用Spring Boot在Web应用程序的服务器上运行。

What we want to happen is: 1) Work is submitted as our custom Runnable object 2) Work completes when it gets its turn (it's a database operation, and we don't need any return value except perhaps returning "Success" if the run() completed without exceptions) 我们想要发生的是:1)工作作为我们的自定义Runnable对象提交2)工作轮到它完成时(它是数据库操作,并且不需要任何返回值,除非运行即可返回“成功” ()已完成,无例外)

However, in our JUnit tests, it seems all the tasks submitted to an ExecutorService or CompletionService disappear when the main thread is finished, unless we call take() every time we add a new task (since it blocks until a task is finished, this makes tasks run sequentially, which defeats the purpose) or if we maintain a list of futures and call a method to loop through the list and get() the value of each feature. 但是,在我们的JUnit测试中,似乎主线程完成后,提交给ExecutorService或CompletionService的所有任务都会消失,除非每次添加新任务时都调用take()(因为它阻塞直到任务完成,所以这使任务按顺序运行(这会违背目的)),或者如果我们维护期货列表并调用一种方法来遍历列表并获取每个功能的值的方法。

The latter option we don't think is ideal because as a server application, we will have requests constantly coming in from different users and don't know how to detect when we should be clearing out the list of futures. 我们认为后一种选择不是理想的选择,因为作为服务器应用程序,我们将不断收到来自不同用户的请求,并且不知道如何检测何时应该清除期货清单。

Why do the threads silently disappear and what is a way around this? 为什么线程会静默消失,如何解决呢?

Don't run the code async: Just test the Runnable directly: 不要异步运行代码:只需直接测试Runnable

@Test
public void test() {
    Runnable r = <your runnable>;
    r.run();
    // various assertions
}

It's pointless testing that your chosen ExecutorService does its job - you can assume that. 您选择的ExecutorService完成其工作是毫无意义的测试-您可以假设这样做。

If you want to assert that your application is behaving correctly, use functional tests; 如果您想断言您的应用程序行为正确,请使用功能测试; ie, spin up a container (eg using @SpringJUnit4ClassRunner ) with a hypersonic datasource, hit the spring boot end point then make you assertions about effect on the database. 即,使用超音速数据源启动一个容器(例如,使用@SpringJUnit4ClassRunner ),击中spring boot的端点,然后使您断言对数据库的影响。

If you use spring boot's @Async annotation for your service, you can even provide a configuration that uses a SynchronousTaskExecutor so you don't have to pause in your test before making assertions. 如果您对服务使用spring boot的@Async批注,则甚至可以提供使用SynchronousTaskExecutor的配置,因此您不必在断言之前暂停测试。

One good approach to testing async code is to block the main test thread and perform assertions in callbacks using something like ConcurrentUnit . 测试异步代码的一种好方法是使用ConcurrentUnit之类的方法阻塞主测试线程并在回调中执行断言。 Here's an example using a CompletableFuture's whenComplete callback: 这是一个使用CompletableFuture的whenComplete回调的whenComplete

Waiter waiter = new Waiter();

CompletableFuture<Connection> future = someService.connect();
future.whenComplete((connection, failure) -> {
  // Called from some other thread
  waiter.assertNotNull(connection);
  waiter.assertNull(failure);
  waiter.resume();
});

// Block the main test thread
waiter.await();

If either of the assertions in the callback thread fail, the test will fail as expected. 如果回调线程中的任何一个声明失败,则测试将按预期失败。 The main test thread will await a resume call before completing the test. 主测试线程将在完成测试之前等待resume调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不关闭的情况下等待 ExecutorService 完成? - How to wait for ExecutorService to finish without shutdown? 如何使用ExecutorService和Futures处理TimeoutException? - How to handle TimeoutException with ExecutorService and Futures? 如何在Java ExecutorService中调试返回期货的Callable - How to debug a Callable in Java ExecutorService that returns Futures 我什么时候应该在 ExecutorService 上使用 CompletionService? - When should I use a CompletionService over an ExecutorService? 使用CompletionService时执行executorService.awaitTermination - Enforce executorService.awaitTermination while using CompletionService 无需定期轮询的CompletionService - CompletionService without regular polling 在Java中:如何在不等待使用ExecutorService完成作业的情况下终止所有线程的执行? - in java: how can i terminate execution of all threads without waiting for them to finish their jobs using ExecutorService? 如何使用 ExecutorService 等待所有线程完成? - How to wait for all threads to finish, using ExecutorService? ExecutorService,如何等待所有任务完成 - ExecutorService, how to wait for all tasks to finish 如何知道哪些调用在 CompletionService 中引发异常? - How to get to know what calls are throwing exception in CompletionService?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM