Optimizing Web Request Performance with Multithreading and Caching in Java Servlets

The article explains how multithreading can improve web request throughput and scalability, illustrates performance gains with example I/O tasks, discusses pitfalls of shared HashMap in servlets, and presents thread‑safe caching solutions using ConcurrentHashMap and FutureTask to reduce latency and avoid concurrency bugs.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Optimizing Web Request Performance with Multithreading and Caching in Java Servlets

Multithreading is primarily used to increase throughput and scalability; in web servers, it allows handling multiple requests concurrently rather than one request per thread.

A simple example shows three slow I/O operations (each 10 ms) followed by quick processing (1 ms each). Executed sequentially the request takes 34 ms, but distributing the three I/O steps across three threads reduces the total time to about 12 ms.

When one I/O step becomes much slower (e.g., the third file read takes 28 ms), parallel execution yields only modest improvement (30 ms total) and may not justify added complexity.

To address the bottleneck, the article proposes caching file data. The first code snippet uses a static HashMap<String, String> fileName2Data to store file contents after the first read:

public class MyServlet extends Servlet {<br/>    private static Map<String, String> fileName2Data = new HashMap<>();<br/>    private void processFile3(String fName) {<br/>        String data = fileName2Data.get(fName);<br/>        if (data == null) {<br/>            data = readFromFile(fName); // 28 ms<br/>            fileName2Data.put(fName, data);<br/>        }<br/>        // process with data<br/>    }<br/>}

This approach fails in a multithreaded servlet because HashMap is not thread‑safe; concurrent modifications can corrupt the map and cause server hangs.

Replacing HashMap with ConcurrentHashMap<String, String> makes the cache thread‑safe:

public class MyServlet extends Servlet {<br/>    private static ConcurrentHashMap<String, String> fileName2Data = new ConcurrentHashMap<>();<br/>    private void processFile3(String fName) {<br/>        String data = fileName2Data.get(fName);<br/>        if (data == null) {<br/>            data = readFromFile(fName); // 28 ms<br/>            fileName2Data.put(fName, data);<br/>        }<br/>        // process with data<br/>    }<br/>}

Even with ConcurrentHashMap, many threads may still read the same file simultaneously, leading to redundant I/O. The article therefore introduces a cache of FutureTask objects combined with putIfAbsent and an ExecutorService to ensure only one thread loads a file while others wait for the result:

public class MyServlet extends Servlet {<br/>    private static ConcurrentHashMap<String, FutureTask<String>> fileName2Data = new ConcurrentHashMap<>();<br/>    private static ExecutorService exec = Executors.newCachedThreadPool();<br/>    private void processFile3(String fName) {<br/>        FutureTask<String> task = fileName2Data.get(fName);<br/>        if (task == null) {<br/>            task = new FutureTask<>(() -> readFromFile(fName));<br/>            FutureTask<String> existing = fileName2Data.putIfAbsent(fName, task);<br/>            if (existing == null) {<br/>                exec.execute(task);<br/>            } else {<br/>                task = existing;<br/>            }<br/>        }<br/>        String data = task.get();<br/>        // process with data<br/>    }<br/>    private FutureTask<String> newFutureTask(final String file) {<br/>        return new FutureTask<>(new Callable<String>() {<br/>            public String call() { return readFromFile(file); }<br/>        });<br/>    }<br/>    private String readFromFile(String file) { return ""; }<br/>}

The article notes that all code is illustrative and may need adjustments for production use.

Typical multithreading scenarios include web servers, dedicated game servers, background tasks such as mass email sending, asynchronous operations like logging or posting to social media, and distributed computing workloads.

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.

JavamultithreadingServlet
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.