El enunciado es: Implementar el modelo del productor / consumidor.
La solución aportada no comprueba el tamaño del buffer, considera que nunca se va a llenar tanto el buffer como para que falle el programa por desbordamiento (supone que los consumidores se encargarán de variar el buffer para que no se llene demasiado). Puede que esto no sea correcto en algunos entornos y sea necesario controlar la inserción de elementos en el buffer.
Buffer.java
package productorconsumidor; import java.util.LinkedList; class Buffer { private LinkedList<Integer> num = new LinkedList<>(); synchronized void poner(int i) { num.add(i); notify(); } synchronized int quitar() { while (num.size() < 1) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return (int) num.remove(); } }
Consumidor.java
package productorconsumidor; class Consumidor extends Thread { private Buffer b; Consumidor(Buffer b) { this.b = b; } public void run() { while (true) { System.out.println("Se quita " + b.quitar() + " desde " + getId()); try { Thread.sleep((long) (Math.random() * 4000 + 1)); } catch (InterruptedException ex) { } } } }
Productor.java
package productorconsumidor; class Productor implements Runnable { private Buffer b; Productor(Buffer b) { this.b = b; } public void run() { int i = 0; while (true) { try { Thread.sleep((long) (Math.random() * 1000 + 1)); } catch (InterruptedException ex) { } System.out.println("Se pone " + i++); b.poner(i); } } }
ProductorConsumidor.java
package productorconsumidor; public class ProductorConsumidor { public static void main(String[] args) { Buffer b = new Buffer(); new Thread(new Productor(b)).start(); new Consumidor(b).start(); new Consumidor(b).start(); new Consumidor(b).start(); } }
Puedes ver todos mis ejercicios de JAVA en este enlace.