Java.Multithreading.What about synchronization and multithreading issues in servlet container ? Do we have smth right out of the box ?

🧵 Servlets Are Multithreaded by Default

When multiple clients send requests to the same servlet, the servlet container creates a new thread for each request, but only one instance of the servlet is created and shared across threads.

⚠️ This means:

If your servlet has shared mutable state, you can run into race conditions, data corruption, and thread-safety issues.


🛑 Example of a Thread Safety Issue

public class CounterServlet extends HttpServlet {
    private int counter = 0;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        counter++; // 💣 Race condition!
        res.getWriter().write("Counter: " + counter);
    }
}

This servlet is not thread-safe. Multiple requests can corrupt the counter variable.

✅ How to Make It Thread-Safe

1. Use Local Variables (Preferred)

Local variables are stored on the thread’s stack, so each thread gets its own copy.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    int localCounter = 0;
    localCounter++; // Safe
    res.getWriter().write("Local Counter: " + localCounter);
}

2. Synchronize Access

If you must use shared state, synchronize access:

private int counter = 0;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    synchronized (this) {
        counter++;
        res.getWriter().write("Counter: " + counter);
    }
}

But this can lead to bottlenecks — only one thread at a time enters the block.

3. Use Concurrent Utilities

Java gives you thread-safe classes out of the box:

private final AtomicInteger counter = new AtomicInteger();

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    int current = counter.incrementAndGet();
    res.getWriter().write("Counter: " + current);
}

Or use:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • ReentrantLock (more control than synchronized)
  • ThreadLocal (for per-thread data)

🔒 Servlet Container Itself Ensures:

  • Each request runs in its own thread
  • Only one servlet instance per declaration
  • ServletContext and ServletConfig are shared objects — be careful!

❌ Not Thread-Safe by Default:

  • Instance variables in servlets
  • Shared objects like lists or maps without synchronization

✅ Thread-Safe by Default:

  • Local variables inside doGet() / doPost()
  • Immutable objects (String, Integer, etc.)
  • ThreadLocal for per-request storage

🧠 Summary

FeatureThread-Safe?Notes
Local variablesBest choice
Instance variables (mutable)Use synchronized or Atomic types
ServletContext, HttpSessionBe careful when storing mutable data
Java concurrent utilsUse Atomic*, ConcurrentHashMap, etc.
ThreadLocalGreat for request-specific data
This entry was posted in Без рубрики. Bookmark the permalink.