Simulación de un Sistema de Gestión de Pedidos en una Cocina
Enunciado
Diseña un programa en Java que simule el funcionamiento de una cocina en un restaurante. Los clientes envían pedidos que se colocan en una cola compartida, y los cocineros los procesan en el orden en que llegan. La cola tiene un tamaño máximo, por lo que los clientes deben esperar si está llena, y los cocineros deben esperar si no hay pedidos disponibles.
Requisitos
- Clases necesarias:
- Una clase
Cocinaque gestione los pedidos en una cola compartida. - Una clase
Clienteque represente a los hilos que generan pedidos. - Una clase
Cocineroque represente a los hilos que procesan los pedidos.
- Una clase
- Gestión de pedidos:
- Los clientes colocan pedidos en la cola.
- Los cocineros toman pedidos de la cola y los procesan.
- Si la cola está llena, los clientes deben esperar.
- Si la cola está vacía, los cocineros deben esperar.
- Sincronización:
- Usa
wait()ynotifyAll()para coordinar el acceso a la cola.
- Usa
- Simulación:
- Genera 10 clientes que envían un pedido cada uno.
- Genera 3 cocineros que procesan los pedidos.
Implementación
import java.util.LinkedList;
import java.util.Queue;
class Cocina {
private final Queue<String> pedidos = new LinkedList<>();
private final int capacidadMaxima;
public Cocina(int capacidadMaxima) {
this.capacidadMaxima = capacidadMaxima;
}
public synchronized void agregarPedido(String pedido) throws InterruptedException {
while (pedidos.size() == capacidadMaxima) {
System.out.println(Thread.currentThread().getName() + " espera para agregar el pedido: " + pedido);
wait(); // Espera si la cola está llena
}
pedidos.add(pedido);
System.out.println(Thread.currentThread().getName() + " agregó el pedido: " + pedido);
notifyAll(); // Notifica a los cocineros
}
public synchronized String tomarPedido() throws InterruptedException {
while (pedidos.isEmpty()) {
System.out.println(Thread.currentThread().getName() + " espera para tomar un pedido.");
wait(); // Espera si no hay pedidos
}
String pedido = pedidos.poll();
System.out.println(Thread.currentThread().getName() + " tomó el pedido: " + pedido);
notifyAll(); // Notifica a los clientes
return pedido;
}
}
class Cliente implements Runnable {
private final Cocina cocina;
private final String pedido;
public Cliente(Cocina cocina, String pedido) {
this.cocina = cocina;
this.pedido = pedido;
}
@Override
public void run() {
try {
cocina.agregarPedido(pedido);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Cocinero implements Runnable {
private final Cocina cocina;
public Cocinero(Cocina cocina) {
this.cocina = cocina;
}
@Override
public void run() {
try {
while (true) {
String pedido = cocina.tomarPedido();
System.out.println(Thread.currentThread().getName() + " está cocinando: " + pedido);
Thread.sleep(2000); // Simula el tiempo de preparación
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class Restaurante {
public static void main(String[] args) {
Cocina cocina = new Cocina(5); // Cola con capacidad para 5 pedidos
// Crear e iniciar hilos de clientes
for (int i = 1; i <= 10; i++) {
String pedido = "Pedido-" + i;
new Thread(new Cliente(cocina, pedido), "Cliente-" + i).start();
}
// Crear e iniciar hilos de cocineros
for (int i = 1; i <= 3; i++) {
new Thread(new Cocinero(cocina), "Cocinero-" + i).start();
}
}
}
Requisitos de Salida
El programa debe mostrar mensajes como los siguientes:
Cliente-1 agregó el pedido: Pedido-1
Cliente-2 agregó el pedido: Pedido-2
Cocinero-1 tomó el pedido: Pedido-1
Cocinero-1 está cocinando: Pedido-1
Cliente-3 agregó el pedido: Pedido-3
Cliente-4 espera para agregar el pedido: Pedido-4
Cocinero-2 tomó el pedido: Pedido-2
Cocinero-2 está cocinando: Pedido-2
...
Conceptos Evaluados
- Sincronización: Uso de
wait()ynotifyAll()para coordinar la cola de pedidos entre clientes y cocineros. - Gestión de recursos compartidos: Implementación de una cola con capacidad limitada para pedidos.
- Concurrencia: Manejo de múltiples clientes y cocineros trabajando simultáneamente.
Resumen
Este ejercicio combina la sincronización y la gestión de recursos compartidos en un escenario práctico. Permite aplicar conceptos avanzados de concurrencia y programación multihilo en Java, al mismo tiempo que refuerza habilidades clave como el uso de wait() y notifyAll().
