Understanding Synchronous vs Asynchronous, Blocking vs Non‑Blocking, and Full‑Chain Asynchrony in Java Web Applications

This article explains the differences between synchronous, asynchronous, blocking and non‑blocking execution, illustrates their combinations with real‑world analogies, and provides practical guidance on applying servlet async, Spring MVC async, full‑chain async, HTTP client async and database async techniques to improve Java backend throughput and CPU utilization.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding Synchronous vs Asynchronous, Blocking vs Non‑Blocking, and Full‑Chain Asynchrony in Java Web Applications

In modern Java web projects, distinguishing between synchronous/asynchronous and blocking/non‑blocking execution is essential for improving performance.

1. Synchronous vs Asynchronous, Blocking vs Non‑Blocking

Synchronous : the caller waits for the result before proceeding.

Asynchronous : the caller does not wait; the result is delivered later via callbacks, notifications, etc.

Blocking : the thread is suspended until the result arrives.

Non‑blocking : the thread can continue doing other work while waiting.

Four combinations are illustrated with simple store‑shopping analogies:

Synchronous + Blocking – wait in the store doing nothing.

Synchronous + Non‑blocking – poll the store while doing other tasks.

Asynchronous + Blocking – submit a task and immediately block on future.get().

Asynchronous + Non‑blocking – give the store a phone number and continue other work; when the item is ready, the store calls back.

In high‑concurrency systems, the asynchronous + non‑blocking model is the most efficient because it keeps worker threads busy.

2. Synchronous Blocking vs Asynchronous Non‑Blocking

When an RPC or HTTP call is made synchronously, the handling thread is blocked, leading to low CPU utilization. By switching to asynchronous non‑blocking, the request thread can start the I/O operation, register a callback, and immediately return to process other requests, dramatically increasing QPS.

Two main bottlenecks are:

CPU‑bound work (e.g., data processing, serialization) – requires algorithmic or framework optimizations.

I/O‑wait (network, file I/O) – can be mitigated with asynchronous techniques.

3. What Can Be Asynchronized?

Servlet async, Spring MVC async.

RPC calls (Dubbo, Thrift) and HTTP calls.

Database and cache calls.

4. Servlet Asynchrony

Traditional servlet handling is synchronous and blocking. After Servlet 3.0, async support allows the servlet thread to release the container thread while the business logic runs in a separate thread.

@WebServlet(name="WorkServlet", urlPatterns="/work", asyncSupported=true)
public class WorkServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/plain;charset=UTF-8");
        resp.setHeader("Cache-Control", "private");
        resp.setHeader("Pragma", "no-cache");
        PrintWriter writer = resp.getWriter();
        List<String> zuoyes = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            zuoyes.add("zuoye" + i);
        }
        AsyncContext ac = req.startAsync();
        ac.setTimeout(1*60*60*1000L);
        ac.start(new Runnable() {
            @Override
            public void run() {
                try {
                    PrintWriter writer = ac.getResponse().getWriter();
                    for (String zuoye : zuoyes) {
                        writer.println("\"" + zuoye + "\"请求处理中");
                        Thread.sleep(1*1000L);
                        writer.flush();
                    }
                    ac.complete();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Key points: the servlet container thread is released; the AsyncContext holds the long‑lived connection, similar to keeping a phone number for later callbacks.

4.1 Spring MVC Asynchrony

Spring MVC abstracts the servlet async mechanism. Controllers return DeferredResult<String> (or WebAsyncTask) and the framework handles request forwarding, allowing filters to run only once. Example configuration:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.2.3.RELEASE</version>
</dependency>

Web.xml must declare async‑supported for both servlet and filter:

<filter>
    <filter-name>testFilter</filter-name>
    <filter-class>com.TestFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <async-supported>true</async-supported>
</servlet>

In a filter you can detect a Spring MVC forward by checking the WEB_ASYNC_MANAGER_ATTRIBUTE attribute.

5. Full‑Chain Asynchrony

Even with servlet async, the business thread may still block on I/O. Full‑chain async moves every I/O operation to a non‑blocking NIO client, keeping CPU cores fully utilized. The diagram shows the flow from request → NIO client → reactor → thread pool.

5.1 Remote Call Asynchrony (HTTP)

Apache HttpAsyncClient provides a fully non‑blocking HTTP client. Example configuration:

IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setIoThreadCount(1).build();
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager conManager = new PoolingNHttpClientConnectionManager(ioReactor);
conManager.setMaxTotal(100);
conManager.setDefaultMaxPerRoute(100);
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
        .setConnectionManager(conManager)
        .build();
httpclient.start();

HttpGet request1 = new HttpGet("http://www.apache.org/");
Future<HttpResponse> future = httpclient.execute(request1, null);
HttpResponse response1 = future.get();
System.out.println(request1.getRequestLine() + "->" + response1.getStatusLine());

HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback<HttpResponse>() {
    @Override
    public void completed(HttpResponse response2) {
        System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
    }
    @Override
    public void failed(Exception ex) {
        System.out.println(request2.getRequestLine() + "->" + ex);
    }
    @Override
    public void cancelled() {
        System.out.println(request2.getRequestLine() + " cancelled");
    }
});

The client uses a PoolingNHttpClientConnectionManager that contains a Reactor (handles I/O events) and a CPool (manages connections, max total, per‑route limits).

5.2 Database Call Asynchrony

Most JDBC frameworks are synchronous; you can either wrap calls in your own async wrapper or use open‑source solutions such as Zebra DAO which provides asynchronous APIs.

6. Conclusion

Asynchrony is not a silver bullet, but applying asynchronous non‑blocking patterns at the servlet, framework, remote‑call and database layers can significantly increase QPS and overall throughput of Java backend services.

Source: https://mp.weixin.qq.com/s/RFh2uePvSq_tnz93n4Alrw
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.

Javaasynchronous programmingServletSpring MVCHTTP client
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.