Implementación de Patrón Productor-Consumidor con Hilos en Java
Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones
Escrito el en
español con un tamaño de 5,64 KB
Implementación de Sistema de Producción y Empaquetado con Hilos
A continuación, se presenta el código fuente corregido y formateado, enfocado en la implementación del patrón Productor-Consumidor utilizando hilos en Java para simular el ensamblaje y empaquetado de hamburguesas.
Clase RobotEmpaquetador (Consumidor)
Esta clase representa a los robots encargados de tomar y empaquetar un tipo específico de hamburguesa del mostrador compartido.
class RobotEmpaquetador extends Thread {
private Mostrador buff;
private String tipoHamburguesa;
// En el constructor se recibe el objeto Mostrador, que es compartido
public RobotEmpaquetador(Mostrador buff, String tipoHamburguesa) {
this.buff = buff;
this.tipoHamburguesa = tipoHamburguesa;
}
@Override
public void run() {
// Para toda la vida
while(true) {
// Esperamos un tiempo y consumimos
try {
Thread.sleep(95);
// Este robot concreto debe consumir el tipo de hamburguesa que ha recibido
// en el constructor
buff.consumir(tipoHamburguesa);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
Clase RobotEnsamblador (Productor)
Este hilo se encarga de producir aleatoriamente una de las hamburguesas disponibles y colocarla en el mostrador.
class RobotEnsamblador extends Thread {
private Mostrador buff;
private String[] opciones = {"smash", "vegan", "chicken"};
// En el constructor se recibe el objeto Mostrador, que es compartido
public RobotEnsamblador(Mostrador buff) {
this.buff = buff;
}
@Override
public void run() {
while (true) {
// Esperamos un tiempo y producimos
try {
Thread.sleep((int)(Math.random() * 31) + 20);
// Saco aleatoriamente una hamburguesa de entre las 3 que hay cada vez
// y trato de empaquetarla
String hamburguesAProducir = opciones[(int)(Math.random() * opciones.length)];
buff.producir(hamburguesAProducir);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Clase Mostrador (Buffer Compartido)
Esta clase actúa como el buffer compartido y gestiona la sincronización entre productores y consumidores mediante los métodos wait() y notifyAll().
Métodos de Sincronización
producir(String contenido): Añade una hamburguesa si hay espacio. Si el mostrador está lleno, el hilo espera.consumir(String tipoHamburguesaACoger): Intenta retirar una hamburguesa específica. Si el mostrador está vacío o no contiene el tipo solicitado, el hilo espera.
// Objeto compartido (buffer)
class Mostrador {
private int elementosMax;
private ArrayList<String> cola = new ArrayList<>();
public Mostrador(int elementosMax) {
this.elementosMax = elementosMax;
}
public synchronized void producir(String contenido) {
// Compruebo si el mostrador está lleno, en cuyo caso me espero porque no hay hueco
while(this.cola.size() == elementosMax) {
try {
System.out.println("😢 Esperando que haya hueco en el mostrador para ensamblar una nueva hamburguesa...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Si estoy aquí es que hay hueco, produzco la hamburguesa
this.cola.add(contenido);
System.out.println("🍔 Ensamblada: "+contenido);
// Notifico a los hilos para que se despierten y puedan ensamblar
notifyAll();
}
public synchronized void consumir(String tipoHamburguesaACoger) {
// En caso de que no haya ninguna hamburguesa
// o bien no exista del tipo que quiero empaquetar, me quedo esperando
while(this.cola.isEmpty() || !this.cola.contains(tipoHamburguesaACoger)) {
try {
System.out.println("⌚ Esperando a que haya una "+tipoHamburguesaACoger+" para poder empaquetarla...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Si estoy aquí es que hay una hamburguesa para empaquetar en el mostrador
this.cola.remove(tipoHamburguesaACoger);
System.out.println("🍴 Empaquetada: "+tipoHamburguesaACoger);
// Notifico al hilo para que se despierte y puedan producir en el nuevo hueco
notifyAll();
}
}
Clase Principal RoboBurguer
Configuración inicial y arranque de todos los hilos concurrentes.
public class RoboBurguer {
public static void main(String[] args) {
// Creo los elementos de mi programa
Mostrador mostrador = new Mostrador(10);
// Inicialización de Robots Empaquetadores (Consumidores)
Thread emp1 = new RobotEmpaquetador(mostrador, "vegan");
Thread emp2 = new RobotEmpaquetador(mostrador, "chicken");
Thread emp3 = new RobotEmpaquetador(mostrador, "smash");
// Inicialización de Robot Ensamblador (Productor)
Thread ens = new RobotEnsamblador(mostrador);
// Los arranco
emp1.start();
emp2.start();
emp3.start();
ens.start();
}
}