El servidor del tema anterior atiende una petición a la vez. La solución es combinar ambas ideas: un pool de hilos del tema 3 atendiendo las conexiones del servidor de sockets.
public class ConcurrentHttpServer {
private static final ExecutorService POOL = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
while (true) {
Socket socket = serverSocket.accept();
POOL.execute(() -> handle(socket));
}
}
}
private static void handle(Socket socket) {
try (socket) {
// leer petición y responder como en el tema 02
} catch (IOException exception) {
// registrar el error
}
}
}
accept() devuelve el Socket y el bucle principal queda libre para aceptar la siguiente conexión.
static compartido → condición de carrera entre peticiones.ThreadLocal sin limpiar → fuga de datos a la siguiente petición del mismo hilo.Java incluye un servidor HTTP con pool de hilos integrado, útil como alternativa intermedia entre el servidor propio y Tomcat:
public class JdkHttpServer {
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/books", exchange -> {
String body = "{\"message\":\"books endpoint\"}";
exchange.getResponseHeaders().set("Content-Type", "application/json");
exchange.sendResponseHeaders(200, body.getBytes().length);
try (OutputStream output = exchange.getResponseBody()) {
output.write(body.getBytes());
}
});
server.setExecutor(Executors.newFixedThreadPool(10));
server.start();
}
}
HttpServer resuelve el parseo del protocolo; el Executor gestiona el pool. Lo que sigue sin resolver: enrutado por rutas, archivos estáticos, ciclo de vida de componentes… Eso es exactamente lo que aporta un contenedor de servlets.
| Capa | Problema que resuelve |
|---|---|
| Sockets | Comunicación TCP |
| Pool de hilos | Concurrencia entre peticiones |
| HttpServer / contenedor | Protocolo HTTP, enrutado, recursos |
| Tomcat | Todo lo anterior + ciclo de vida de servlets y filtros |