Why Misusing Spring @Async Can Crash Your System – and How to Avoid It

This article reveals how creating a new thread pool for each @Async method in Spring can exhaust system resources, explains Spring Boot’s default executor behavior, shows code examples, and offers practical guidance to prevent thread‑pool related crashes in Java backend applications.

macrozheng
macrozheng
macrozheng
Why Misusing Spring @Async Can Crash Your System – and How to Avoid It

Long ago I experienced a painful fault caused by reckless thread‑pool usage: a teammate enabled a "brutal" thread‑pool mode, creating a separate pool for every method call. When request volume rises, the operating system is overwhelmed and all business logic becomes unresponsive.

1. Spring's Asynchronous Code

Spring, the beloved Java framework, offers the @Async annotation for easy async execution. Yet many developers blindly apply it, ignoring the multithreading complexities it introduces.

Below is a minimal Spring Boot project that enables async support:

@SpringBootApplication<br/>@EnableAsync<br/>public class DemoApplication {<br/>    // ...<br/>}

Define a component with an @Async method:

@Component<br/>public class AsyncService {<br/>    @Async<br/>    public void async() {<br/>        try {<br/>            Thread.sleep(1000);<br/>            System.out.println(Thread.currentThread());<br/>        } catch (Exception ex) {<br/>            ex.printStackTrace();<br/>        }<br/>    }<br/>}

Create a test endpoint that triggers the async method:

@ResponseBody<br/>@GetMapping("test")<br/>public void test() {<br/>    service.async();<br/>}

When the endpoint is called, a breakpoint reveals the thread pool used by the async task.

The default async executor uses a ThreadPoolTaskExecutor with corePoolSize=8 and an unbounded LinkedBlockingQueue. Tasks beyond eight threads are queued indefinitely, leading to massive backlog, severe latency, or even OOM errors under high load.

throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, var4);

Specifying a custom ThreadPoolExecutor can mitigate the issue, but many teams overlook this.

2. Spring Boot Saves You

Spring Boot’s TaskExecutionAutoConfiguration automatically provides a ThreadPoolTaskExecutor bean, preventing the need to configure one manually.

@ConditionalOnMissingBean({Executor.class})<br/>public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {<br/>    return builder.build();<br/>}

If Boot is absent, Spring falls back to SimpleAsyncTaskExecutor, which creates a brand‑new thread for every task.

@Override<br/>@Nullable<br/>protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {<br/>    Executor defaultExecutor = super.getDefaultExecutor(beanFactory);<br/>    return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());<br/>}

The design of SimpleAsyncTaskExecutor is dangerous: each execution spawns a separate thread, so a TPS of 1000 would generate 1000 threads per second, quickly exhausting the OS.

protected void doExecute(Runnable task) {<br/>    Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));<br/>    thread.start();<br/>}

3. End

Using a new‑thread‑per‑task approach is hazardous. Many Spring components, such as AsyncRestTemplate, still rely on SimpleAsyncTaskExecutor, exposing applications to uncontrolled thread creation and potential crashes.

It is strongly recommended to blacklist SimpleAsyncTaskExecutor in your projects and replace it with a properly configured thread pool.

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.

BackendThreadPoolasync
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.