class Casella {
        private int info;
        private boolean piena;
        private String dest;

        private void mess(String s) {
                System.out.println(Thread.currentThread().getName() +
                 ": " + s);
        }

        public synchronized void invia(int i, String dest) throws InterruptedException {
                while (piena) {
                        //mess("mi sospendo");
                        wait();
                        //mess("riprovo a inviare");
                }
                System.out.println(Thread.currentThread().getName()
                        + ": inviato " + i + " per " + dest);
                piena = true;
                this.dest = dest;
                info = i;
                notifyAll();
        }

        public synchronized int ricevi() throws InterruptedException {
                while (!piena || !Thread.currentThread().getName().equals(dest)) {
                        //mess("mi sospendo");
                        wait();
                        //mess("riprovo a ricevere");
                }

                System.out.println(Thread.currentThread().getName()
                        + ": ricevuto " + info + " per " + dest);
                piena = false;
                notifyAll();
                return info;
        }
}

class Produttore extends Thread {
        private Casella c;
        Produttore(String id, Casella c) {
                super(id);
                this.c = c;
                start();
        }

        public void run() {
                try {
                        for (int i = 0; i < 10; i++) {
                                c.invia(i, "Cons" + i);
                        }
                } catch (InterruptedException e) {
                }
        }
}


class Consumatore extends Thread {
        private Casella c;                                    
        Consumatore(String id, Casella c) {
                super(id);
                this.c = c;
                start();
        }
        public void run() {
                int j;
                try {
                        for (int i = 0; i < 10; i++) {
                                j = c.ricevi();
                        }
                } catch (InterruptedException e) {
                }
        }
}


class ProvaCasella {
        public static void main(String[] args) {
                Casella c = new Casella();
                for (int i = 0; i < 10; i++)
                        new Produttore("Prod" + i, c);
                for (int i = 0; i < 10; i++)
                        new Consumatore("Cons" + i, c);
        }
}

