I have written several articles about how to use @async to implement asynchronous calls, and I have received a lot of feedback from children. Among them, there are many problems about the use of return Future and timeout control for asynchronous execution, so this article will talk about how to deal with these two problems.

If you are not familiar with the use of @async annotations, you can check out the previous article as follows:

  • Use @async to make asynchronous calls
  • Asynchronous invocation with @async: Custom thread pool
  • Use @async for asynchronous invocation: Resources close gracefully

Defining asynchronous Tasks

First, we define an asynchronous task using the @async annotation. This method returns the Future type as follows:

@Slf4j
@Component
public class Task {

    public static Random random = new Random();

    @Async("taskExecutor")
    public Future<String> run(a) throws Exception {
        long sleep = random.nextInt(10000);
        log.info("Start task, time required:" + sleep + "毫秒");
        Thread.sleep(sleep);
        log.info("Complete the mission");
        return new AsyncResult<>("test"); }}Copy the code

What is itFutureType?

Future is an interface for canceling, querying, and retrieving the results of a specific Runnable or Callable task. If necessary, the results of the execution can be obtained through the GET method, which blocks until the task returns results.

Its interface is defined as follows:

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled(a);
    boolean isDone(a);
    V get(a) throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
Copy the code

It states five such methods:

  • The cancel method is used to cancel a task, returning true on success or false on failure. The mayInterruptIfRunning parameter indicates whether ongoing tasks that have not completed are allowed to be canceled, and true indicates that ongoing tasks can be canceled. Whether mayInterruptIfRunning is true or false, this method must return false if the task is completed, or if you cancel the completed task. True if the task is executing and false if mayInterruptIfRunning is set to true. If the task has not yet been executed, true is always returned regardless of whether mayInterruptIfRunning is true or false.
  • The isCancelled method indicates whether the task was cancelled successfully or returns true if the task was cancelled before it completed normally.
  • The isDone method indicates whether the task is complete, and returns true if it is.
  • The get() method is used to get the result of the execution, which blocks and does not return until the task is finished.
  • Get (long timeout, TimeUnit Unit) is used to obtain the execution result. If no result is obtained within the specified time, null is returned.

In other words, Future provides three functions:

  1. Judge whether the task is completed;
  2. Can interrupt the task;
  3. Obtain the task execution results.

Test execution and define timeout

After completing the asynchronous task definition that returns the Future, let’s try to implement a unit test to execute the task using the Future, such as:

@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private Task task;

    @Test
    public void test(a) throws Exception {
        Future<String> futureResult = task.run();
        String result = futureResult.get(5, TimeUnit.SECONDS); log.info(result); }}Copy the code

In the above code, we also define the timeout time for the thread to execute in the get method. By executing this test, we can observe that if the execution time exceeds 5 seconds, we will raise the timeout exception, and the thread will be released back to the thread pool because of the timeout.

Complete example:

Readers can view chapter4-5 projects in the following two warehouses according to their preferences:

  • Github:https://github.com/dyc87112/SpringBoot-Learning/
  • Gitee:https://gitee.com/didispace/SpringBoot-Learning/

If you are interested in these, welcome to star, follow, favorites, forward to give support!