El patron productor - consumidor es uno de los patrones mas basicos de la sincronizacion de procesos. Lo importante es identificar cuando debe ser usado. Para el siguiente tutorial propongo la siguiente situacion:
En un parqueadero los carros entran constantemente, y existen varias secciones. Sin embargo solo hay un ascensor y pueden entrar uno a la vez y una gran grua los situa en cada seccion.
Este seria un claro ejemplo de productor - consumidor, productor serian los carros que aparecen constantemente, consumidor la grua que los coloca en cada seccion. Tambien podemos identificar un buffer es decir el numero de secciones. Finalmente el ascensor seria una especie de monitor que controla que existan carros por el productor y el consumidor este libre para colocarlos.
Comencemos con la clase Productor, que es una thread que va a crear nuevos objectos de la clase "Car", los va agregando en una cola y pone el ultimo elemento de la cola en el ascensor.
public class Producer extends Thread { Lift lift; //Queue of cars waiting to park public static Queue<Car> carsOnWait = new LinkedList<Car>(); public Producer(Lift lift) { super(); this.lift = lift; } public void run() { while (true) { try { Car car = Car.getNewCar(); carsOnWait.add(car); System.out.println("[" + car.getId() + "] in line"); /** * Get car on the lift only if it's available and on the ground floor */ lift.put(carsOnWait.element()); Producer.carsOnWait.remove(); Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Producer Interrupted"); } } }
La clase Lift o ascensor es un monitor que va a ser usado para controlar que el consumidor consuma mientras haya carros y el productor produzca mientras el consumidor no este ocupado. Para ello usamos las instrucciones "wait()" and notifyAll()
public class Lift { private boolean inUse = false; Car carOnLift; public synchronized void put(Car car) throws InterruptedException { while (inUse == true) { try { wait(); } catch (InterruptedException e) { } } System.out.println("[" + car.getId() + "] in elevator going UP "); carOnLift = car; inUse = true; notifyAll(); } /** * Get Car used by Consumer * @return * @throws InterruptedException */ public synchronized Car get() throws InterruptedException { while (inUse == false ) { try { wait(); } catch (InterruptedException e) { } } inUse = false; notifyAll(); return carOnLift; } }
Finalmente, la clase Consumer obtiene carros del ascensor y luego simplemente imprime un mensaje del carro siendo consumido.
public class Consumer extends Thread { Lift lift; public Consumer(Lift lift) { super(); this.lift = lift; } public void run() { Car car; while (true) { try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } try { // Get car from Lift otherwise wait car = lift.get(); System.out.println("[" + car.getId() + "] Launching vehicle "); } catch (InterruptedException e) { e.printStackTrace(); } } } }
La clase Productor y Consumidor correran indefinidamente durante la ejecucion del programa. Este ejemplo pueden extenderlo para incluir un buffer que controle el numero de secciones del parqueadero.
El codigo completo lo pueden encontrar Aquí
Productor - Consumidor En Java (Parqueadero De Carros) >>>>> Download Now
ResponderEliminar>>>>> Download Full
Productor - Consumidor En Java (Parqueadero De Carros) >>>>> Download LINK
>>>>> Download Now
Productor - Consumidor En Java (Parqueadero De Carros) >>>>> Download Full
>>>>> Download LINK LT