Servlet Basic Practices
Servlets are Java programs that handle multiple client requests at the same time.
To build efficient, safe, and maintainable web applications, you must follow some key practices — mainly in
Thread Safety, Resource Management, and Code Organization.
1️⃣ Thread Safety in Servlets
Servlets are multi-threaded — meaning the server (like Tomcat) creates only one instance of your servlet
and uses multiple threads to handle requests simultaneously.
This can cause problems if you use shared resources (like instance variables) without proper
synchronization.
⚠️Problem Example (Not Thread Safe)
public class CounterServlet extends HttpServlet {
private int counter = 0; // shared by all threads
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
counter++;
[Link]().println("Visitor number: " + counter);
}
}
Issue:
If two users access the servlet at the same time, both threads may modify counter simultaneously, leading
to incorrect or unpredictable output.
✅ Solution 1: Avoid Shared Instance Variables
Use local variables inside methods instead of class-level variables.
public class SafeCounterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int counter = (int) ([Link]() * 1000);
[Link]().println("Random visitor ID: " + counter);
}
}
Each thread has its own copy of local variables → Thread Safe ✅
✅ Solution 2: Synchronization (if shared data is required)
public class SyncCounterServlet extends HttpServlet {
private int counter = 0;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
synchronized (this) {
counter++;
[Link]().println("Visitor number: " + counter);
}
}
}
Here, only one thread can enter the synchronized block at a time.
But remember — synchronization can reduce performance, so use it only when necessary.
✅ Solution 3: Use Atomic Variables
import [Link];
public class AtomicCounterServlet extends HttpServlet {
private AtomicInteger counter = new AtomicInteger(0);
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int count = [Link]();
[Link]().println("Visitor number: " + count);
}
}
AtomicInteger ensures thread-safe increment without locking.
💡 Best Practices for Thread Safety
- Do not store request-specific data in instance variables.
- Prefer local variables or thread-safe objects (like AtomicInteger).
- Synchronize only when absolutely needed.
- Avoid SingleThreadModel (deprecated).
⚙️2️⃣ Resource Management
Servlets often use resources such as database connections, files, or network sockets.
Improper handling can cause memory leaks or poor performance.
✅ Best Practices for Resource Management
1. Close Resources
Always close connections, statements, and result sets.
Connection con = null;
try {
con = [Link](...);
// execute queries
} catch (SQLException e) {
[Link]();
} finally {
if (con != null) [Link]();
}
2. Use Connection Pooling
Instead of creating a new DB connection for every request, use a connection pool via DataSource.
Context ctx = new InitialContext();
DataSource ds = (DataSource) [Link]("java:comp/env/jdbc/MyDB");
Connection con = [Link]();
How Connection Pooling Works
1. At application startup, a pool of pre-created connections is established.
2. When a servlet or DAO (Data Access Object) needs a connection:
It requests a connection from the pool.
Performs database operations.
Returns the connection back to the pool (instead of closing it).
3. The pool manages connections, including:
Maximum and minimum pool size
Idle connection handling
Connection validation
Flow Diagram: [Servlet] --> Request Connection --> [Connection Pool]
Database
Return Connection
3. Avoid Resource Leaks
Close input/output streams.
Use try-with-resources for automatic closing.
try (Connection con = [Link]()) {
// automatically closed
}
4. Use init() and destroy() wisely
Create heavy resources in init() once.
Clean them up in destroy().
public void init() {
[Link]("Servlet initialized!");
}
public void destroy() {
[Link]("Servlet destroyed, resources released.");
}
⚠️Common Mistakes
❌ Creating DB connections inside doGet() or doPost() for every request.
❌ Forgetting to close streams or statements.
❌ Using global variables for resources.
3️⃣ Code Organization in Servlets
Well-organized code makes servlets easier to read, debug, and extend.
✅ Best Practices for Code Organization
Follow MVC Pattern
Servlet → Controller (handles logic and flow)
JSP → View (for presentation)
Java Classes → Model (data, database logic)
1. Separate Business Logic
Avoid writing database or computation code inside doGet() or doPost() directly.
public class UserDAO {
public boolean validateUser(String username, String password) {
// DB logic
return true;
}
}
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
UserDAO dao = new UserDAO();
boolean valid = [Link]("john", "1234");
[Link]().println("Valid user: " + valid);
}
}
2. Use Meaningful Names
Servlet class → LoginServlet, RegisterServlet
JSP pages → [Link], [Link]
3. Handle Exceptions Properly
Use try-catch inside servlets.
Redirect to custom error pages for user-friendly messages.
4. Use Packages
Keep files organized under packages like:
[Link]
[Link]
[Link]
🧠 Summary
Concept - Best Practice - Benefit
Thread Safety - Use local variables, synchronization, Atomic classes - Prevents race conditions
Resource Management - Close connections, use pooling, try-with-resources - Prevents memory leaks
Code Organization - Follow MVC, use DAO classes, handle exceptions - Improves readability & scalability
💬 Interview Questions
1. Why are servlets not inherently thread-safe?
2. How can you make a servlet thread-safe?
3. What is the best way to handle database connections in servlets?
4. What is the role of the init() and destroy() methods?
5. How do you manage shared resources in a servlet?
6. Why is it a bad idea to use instance variables in servlets?
7. What is the purpose of connection pooling?
8. What is the MVC pattern, and why is it used in servlets?
9. How would you organize servlet code for a large project?
10. How can poor resource management impact server performance?