⚙️ ¿Thread por conexión o por petición en Java? Comparativa explicada con tacos 🌮


Cuando hablamos de servidores en Java, una gran pregunta aparece tarde o temprano:
¿Usamos un hilo por conexión o un hilo por cada petición?
En este artículo vamos a explicar de forma clara (y divertida) cómo funcionan estos dos modelos de concurrencia con sockets en Java. Veremos sus ventajas, desventajas, y te daré un ejemplo sabroso con... tacos. 🌮 ¡Vamos allá!
🌐 Conexión vs Petición: ¿Qué significa eso?
Primero, entendamos la diferencia:
- Conexión: canal abierto entre cliente y servidor (como una llamada telefónica).
- Petición: acción que se realiza dentro de una conexión (como hablar durante la llamada).
Una conexión puede tener varias peticiones si usamos HTTP Keep-Alive.
🧵 Modelo 1: Un hilo por conexión
Cada conexión con el cliente tiene su propio hilo, que se mantiene vivo mientras dure la conversación (es decir, mientras el socket esté abierto).
🍽️ Ejemplo: Servidor de pedidos de tacos
public class ServidorPorConexion {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(5050);
System.out.println("🌮 Taquería abierta en el puerto 5050");
while (true) {
Socket cliente = serverSocket.accept();
System.out.println("🌮 Cliente llegó: " + cliente.getInetAddress());
new Thread(() -> manejarCliente(cliente)).start();
}
}
private static void manejarCliente(Socket socket) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String pedido;
while ((pedido = in.readLine()) != null) {
System.out.println("🌮 Preparando: " + pedido);
Thread.sleep(1000); // Simulamos tiempo de preparación
out.println("✅ Pedido listo: " + pedido);
}
} catch (Exception e) {
System.out.println("⚠️ Error con cliente: " + e.getMessage());
}
}
}
✅ Pros:
- Muy fácil de entender e implementar.
- Ideal para cuando hay pocas conexiones concurrentes.
❌ Contras:
- Si hay muchas conexiones, necesitarás muchos hilos.
- Los recursos se agotan rápido.
🔁 Modelo 2: Un hilo por cada petición
Cada petición, incluso dentro de una misma conexión, genera un nuevo hilo.
🌮 Ejemplo: Peticiones individuales por taco
public class ServidorPorPeticion {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(6060);
System.out.println("🌮 Servidor de tacos en el puerto 6060");
List<Socket> clientes = new ArrayList<>();
while (true) {
aceptarClientes(serverSocket, clientes);
procesarPeticiones(clientes);
}
}
private static void aceptarClientes(ServerSocket serverSocket, List<Socket> clientes) {
try {
serverSocket.setSoTimeout(100);
Socket cliente = serverSocket.accept();
clientes.add(cliente);
System.out.println("🙋♂️ Cliente nuevo conectado");
} catch (IOException e) {
// Timeout corto, ignoramos
}
}
private static void procesarPeticiones(List<Socket> clientes) {
for (Socket cliente : clientes) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
if (in.ready()) {
String pedido = in.readLine();
new Thread(() -> {
try {
System.out.println("🌮 Preparando (por petición): " + pedido);
Thread.sleep(1000);
PrintWriter out = new PrintWriter(cliente.getOutputStream(), true);
out.println("✅ Taco servido: " + pedido);
} catch (Exception e) {
System.out.println("❌ Error en la petición: " + e.getMessage());
}
}).start();
}
} catch (IOException e) {
System.out.println("⚠️ Cliente desconectado");
}
}
}
}
✅ Pros:
- Mejor escalabilidad con muchos usuarios haciendo muchas peticiones.
- Se adapta mejor a cargas variables.
❌ Contras:
- Muchos hilos pueden significar muchos context-switches (menos eficiencia).
🧮 Comparativa rápida
Característica | Hilo por Conexión | Hilo por Petición |
Ciclo de vida | Largo (hasta cerrar conexión) | Corto (solo para una petición) |
Cambios de contexto | Bajos | Altos |
Escalabilidad | Limitada por nº de conexiones | Mejor, sin límite de conexiones |
Ideal para... | Apps con pocos clientes fijos | Apps con muchas peticiones variables |
🧠 Conclusión
Ambos modelos tienen su lugar.
- ¿Tienes pocos clientes pero muy activos? Hilo por conexión.
- ¿Tu app recibe muchas peticiones concurrentes y no sabes cuántas vendrán? Hilo por petición.
Recuerda: en la práctica, usarás pools de hilos para mejorar aún más el rendimiento. Este artículo es solo el primer paso hacia servidores más avanzados.
¡Nos vemos en el próximo artículo! 😎
Subscribe to my newsletter
Read articles from Carlos Exposito directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
