Elegant Orchestration and Efficient Execution of Complex Tasks with Spring asyncTool

This guide shows how to integrate asyncTool into a Spring Boot project, configure custom thread pools, define core interfaces, and compose serial, parallel, or mixed task flows with full‑link callbacks, fault tolerance, and performance optimizations for complex multi‑threaded orchestration.

IoT Full-Stack Technology
IoT Full-Stack Technology
IoT Full-Stack Technology
Elegant Orchestration and Efficient Execution of Complex Tasks with Spring asyncTool

Integration into Spring Boot

1. Add dependency

Add the asyncTool dependency to the pom.xml file:

<dependency>
    <groupId>com.jd.platform</groupId>
    <artifactId>asyncTool</artifactId>
    <version>YOUR_VERSION</version>
</dependency>

2. Configure thread pool

asyncTool manages an internal pool, but a custom pool can be supplied. Two configuration approaches are provided.

Custom thread pool

@Configuration
@EnableAsync
public class TaskExecutePool {
    @Autowired
    private TaskThreadPoolConfig config;

    @Bean
    public Executor myTaskAsyncPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(config.getCorePoolSize());
        executor.setMaxPoolSize(config.getMaxPoolSize());
        executor.setQueueCapacity(config.getQueueCapacity());
        executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
        executor.setThreadNamePrefix("MyExecutor-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

Override native Spring async pool

@Configuration
@EnableAsync
public class NativeAsyncTaskExecutePool implements AsyncConfigurer {
    @Autowired
    private TaskThreadPoolConfig config;

    @Bean
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(config.getCorePoolSize());
        executor.setMaxPoolSize(config.getMaxPoolSize());
        executor.setQueueCapacity(config.getQueueCapacity());
        executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
        executor.setThreadNamePrefix("MyExecutor2-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, objects) -> {
            log.error("==========================" + ex.getMessage() + "=======================", ex);
            log.error("exception method:" + method.getName());
        };
    }
}

Core API

IWorker interface

action(T object, Map<String, WorkerWrapper> allWrappers)

: task logic; object is the input, allWrappers provides results of other tasks. defaultValue(): value returned when the task times out or throws an exception.

ICallback interface

begin()

: invoked when the task starts.

result(boolean success, T param, WorkResult<V> workResult)

: invoked with the execution outcome.

WorkerWrapper class

id

: unique identifier of the task. param: input parameter for the task. worker: concrete implementation of the task. callback: callback implementation. depend: strong dependency (must finish before this task runs). next: subsequent task used to define execution order.

Usage examples

Serial tasks

// Define task A
WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerA")
        .worker(new WorkerA())
        .callback(new WorkerA())
        .param(1)
        .build();

// Define task B, dependent on A
WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerB")
        .worker(new WorkerB())
        .callback(new WorkerB())
        .param(2)
        .depend(wrapperA)
        .build();

// Define task C, dependent on B
WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerC")
        .worker(new WorkerC())
        .callback(new WorkerC())
        .param(3)
        .depend(wrapperB)
        .build();

// Submit tasks (only the first task needs to be submitted; dependencies are resolved internally)
Async.beginWork(1000, wrapperA);

Parallel tasks

// Define tasks A, B, C without dependencies
WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>()...build();
WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>()...build();
WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>()...build();

// Submit all at once
Async.beginWork(1000, wrapperA, wrapperB, wrapperC);

Mixed: serial then parallel

// A runs first, then B and C run in parallel
WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>()...build();
WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>()...depend(wrapperA)...build();
WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>()...depend(wrapperA)...build();
Async.beginWork(1000, wrapperA);

Mixed: parallel then serial

// B and C run in parallel, after they finish A runs
WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerA")
        .worker(new WorkerA())
        .callback(new WorkerA())
        .param(null) // will receive results of B and C
        .build();

WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerB")
        .worker(new WorkerB())
        .callback(new WorkerB())
        .param(2)
        .next(wrapperA)
        .build();

WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>()
        .id("workerC")
        .worker(new WorkerC())
        .callback(new WorkerC())
        .param(3)
        .next(wrapperA)
        .build();

Async.beginWork(1000, wrapperB, wrapperC);

Main capabilities

Task orchestration : flexible combination of parallel and serial tasks, allowing developers to define execution order according to business needs.

Dependency management : supports strong and weak dependencies; a task can wait for one or many upstream tasks before executing.

Execution monitoring and callbacks : every task triggers callbacks for start, success, failure, timeout, or being skipped, enabling real‑time monitoring.

Exception handling and fault tolerance : each task can specify a timeout and a default return value; failures of independent tasks do not affect others, while dependent tasks inherit failure status.

Performance optimization : low‑thread design reduces thread creation overhead; the framework is lock‑free and can reuse threads across dependent tasks.

Result management : results can be returned in the order tasks were added or via asynchronous callbacks, avoiding blocking the main thread.

Thread‑pool management : thread pools can be shared across task groups or dedicated per group, offering flexible resource allocation.

Simplified development : asyncTool encapsulates complex concurrency logic, letting developers focus on business logic without deep knowledge of low‑level threading.

Precautions

Thread safety : ensure that task implementations are safe for concurrent execution.

Exception handling : handle exceptions within tasks to prevent cascading failures.

Timeout settings : configure reasonable timeouts to avoid resource waste.

Dependency configuration : correctly set dependencies to achieve the intended execution sequence.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaConcurrencySpring Boottask orchestrationasyncTool
IoT Full-Stack Technology
Written by

IoT Full-Stack Technology

Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.