Ejemplo 9: El restaurante y los pedidos
¿Cómo funciona el sistema de pedidos en un restaurante?
En un restaurante, los meseros (Waiters) toman los pedidos de los clientes y los envían a la cocina. La cocina tiene varios cocineros (Cooks) que preparan los pedidos. Para manejar eficientemente los pedidos, el restaurante utiliza un sistema de colas. Cuando un mesero toma un pedido, lo coloca en una cola de pedidos. Los cocineros toman los pedidos de la cola y los preparan. Una vez que un pedido está listo, el cocinero lo entrega al mesero, quien a su vez lo lleva al cliente.
¿Cómo se asignan los pedidos a los cocineros?
Cuando un mesero coloca un pedido en la cola, el sistema de pedidos asigna automáticamente el pedido al siguiente cocinero disponible. Si todos los cocineros están ocupados preparando otros pedidos, el nuevo pedido permanecerá en la cola hasta que un cocinero esté disponible para prepararlo. Esto asegura que los pedidos se procesen de manera eficiente y que los clientes reciban sus pedidos lo más rápido posible.
¿Cómo se asegura que los clientes reciban sus pedidos de manera eficiente?
El sistema de pedidos en el restaurante está diseñado para minimizar el tiempo de espera de los clientes. Al utilizar una cola para manejar los pedidos, el restaurante puede asegurarse de que los pedidos se procesen en el orden en que fueron recibidos. Además, al asignar automáticamente los pedidos a los cocineros disponibles, el restaurante puede maximizar la eficiencia de la cocina y reducir el tiempo que tarda cada pedido en ser preparado. Esto garantiza que los clientes reciban sus pedidos de manera rápida y eficiente, mejorando su experiencia en el restaurante.
Representación gráfica del sistema de pedidos con Java
Para nuestro ejemplo y para representar gráficamente el sistema de pedidos en un restaurante, podemos utilizar Java con la biblioteca Swing para crear una interfaz gráfica que muestre cómo los pedidos se mueven a través de la cola y cómo los cocineros los procesan. De igual manera, usaremos la clase ConcurrentLinkedQueue para manejar la cola de pedidos de manera segura en un entorno concurrente, ya que simularemos un sistema con múltiples meseros y cocineros, pero solo una barra de pedidos.
Para esto, podemos crear una clase Order que represente cada pedido, una clase Cook que represente a los cocineros y una clase Restaurant que maneje la cola de pedidos y la asignación a los cocineros. La interfaz gráfica mostrará la cola de pedidos y el estado de cada cocinero. Además de un enumerado Dish para representar los diferentes tipos de platos que se pueden pedir en el restaurante con un tiempo aleatorio de preparación, y una clase Order para representar cada pedido con un identificador único y el plato solicitado.
1. Enumerado Dish
public enum Dish {
PASTA(2000, "Pasta"),
BURGER(3000, "Amburguesa"),
SALAD(1000, "Ensalada"),
PIZZA(4000, "Pizza");
final int preparationTime;
final String name;
Dish(int preparationTime, String name) {
this.name = name;
this.preparationTime = preparationTime;
}
public int getPreparationTime() {
return preparationTime;
}
@Override
public String toString() {
return name;
}
}
2. Clase Order
public class Order {
private static int idCounter = 0;
private final int id;
private final Dish dish;
public Order(Dish dish) {
this.id = idCounter++;
this.dish = dish;
}
public int getId() {
return id;
}
public Dish getDish() {
return dish;
}
@Override
public String toString() {
return "Orden #" + id + ": " + dish.toString();
}
}
3. Clase Cook
public class Cook implements Runnable {
private final String name;
private final Restaurant restaurant;
public Cook(String name, Restaurant restaurant) {
this.name = name;
this.restaurant = restaurant;
}
@Override
public void run() {
while (restaurant.hasOrders()) {
Order order = restaurant.takeOrder();
if (order != null) {
System.out.println(name + " está preparando " + order);
try {
Thread.sleep(order.getDish().getPreparationTime());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(name + " ha terminado de preparar " + order);
}
}
}
}
4. Clase Restaurant
import java.util.concurrent.ConcurrentLinkedQueue;
public class Restaurant {
private final ConcurrentLinkedQueue<Order> orderQueue = new ConcurrentLinkedQueue<>();
public void placeOrder(Order order) {
orderQueue.add(order);
System.out.println("Se ha colocado " + order);
}
public Order takeOrder() {
return orderQueue.poll();
}
public boolean hasOrders() {
return !orderQueue.isEmpty();
}
}
5. Clase Main
public class Main {
public static void main(String[] args) {
Restaurant restaurant = new Restaurant();
// Crear cocineros
Cook cook1 = new Cook("Cocinero 1", restaurant);
Cook cook2 = new Cook("Cocinero 2", restaurant);
// Iniciar los hilos de los cocineros
new Thread(cook1).start();
new Thread(cook2).start();
// Simular la colocación de pedidos
restaurant.placeOrder(new Order(Dish.PASTA));
restaurant.placeOrder(new Order(Dish.BURGER));
restaurant.placeOrder(new Order(Dish.SALAD));
restaurant.placeOrder(new Order(Dish.PIZZA));
}
}
En este ejemplo, hemos creado un sistema de pedidos para un restaurante utilizando Java. Los meseros colocan los pedidos en una cola, y los cocineros los toman y los preparan. La interfaz gráfica se puede mejorar para mostrar visualmente la cola de pedidos y el estado de cada cocinero, pero este código proporciona una base sólida para entender cómo funciona el sistema de pedidos en un restaurante.
Ejemplo 8: Control de acceso a recursos compartidos con semáforos
En este artículo se presentará un ejemplo práctico de cómo utilizar semáforos en Java para controlar el acceso a recursos compartidos en un entorno concurrente, evitando condiciones de carrera y garantizando la sincronización entre hilos.
Ejemplo 10: Proceso FIFO (First In, First Out) con Semáforos y Swing
Implementación de un proceso FIFO utilizando semáforos para controlar el acceso a un recurso compartido, con una interfaz gráfica en Swing.