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
Cocina
que gestione los pedidos en una cola compartida. - Una clase
Cliente
que represente a los hilos que generan pedidos. - Una clase
Cocinero
que 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()
.