04.06.2008 | 22:12:22
immagine
Ing. Emanuele Scapin

Java, es 3, Thread 20 bevitori
  • Un gruppo di 20 bevitori ha a disposizione una botte di vino con 3 rubinetti, contenente 100 litri di vino. Di conseguenza possono bere solo tre persone alla volta, sempre che la botte contenga ancora vino. Si suppone per semplicità che ogni bevuta faccia diminuire il vino nella botte di 1 litro. Si simuli la suddetta situazione in Java, utilizzando un Monitor (costrutto synchronized di java). Suggerimento: Il thread bevitore, dopo aver atteso un tempo casuale, deciderà di bere e si metterà in attesa se il numero di rubinetti liberi è 0; quindi controllerà la variabile contenente il vino. Qualora non ci sia più vino il thread terminerà la sua esecuzione).

     

  • Definizione dell'oggetto Botte, propedeutico agli altri oggetti in quanto da essi utilizzato.
    Si notino i metodi synchronized che saranno invocati dalle varie istanze del bevitore per accedere ai dati in comune.

    package bevitori;
    
    public class Botte {
        private int litri = 100;
        private int rubinetti = 3;
        private JFBevitori owner;
        
        public Botte(int litri, int rubinetti, JFBevitori owner) {
            this.litri = litri;
            this.rubinetti = rubinetti;
            this.owner = owner;
        }
        
        public synchronized void Bevi() {
            if (litri > 0) {
              litri--;
              System.out.println("litri = " + litri);
              owner.UpdProgressBar();
            }
            else {
              owner.Termina();
            }
        }
        
        public synchronized boolean PrendoRubinetto() {
            boolean b = false;
            if (rubinetti > 0) {
              rubinetti--;
              b = true;
            }
            return b;
        }   
        
        public synchronized void RilascioRubinetto() {
              rubinetti++;
        }     
    }
            

     

  • Definizione dell'oggetto Bevitore, che implementa il thread.

    package bevitori;
    
    public class Bevitore extends Thread {
        private int litri = 0; // litri bevuti
        private String nome;   // nome bevitore
        private Botte botte;
        private boolean attivo = false;
        
        public Bevitore (String nome, Botte botte) {
            this.nome = nome;
            this.botte = botte;
            attivo = true;
            start();
        }
        
        public void Termina() {
            attivo = false;
            this.stop();
        }
        
        @Override
        public void run() {
            try {
                while(attivo) {
                    double tmp = Math.random();
                    tmp = tmp * 1000; // tempo attesa prima di verificare
                    int tempo = (int) tmp;
                    
                    sleep(tempo);
                    System.out.println("nome, tempo " + tempo);
                    
                    if (botte.PrendoRubinetto()) {
                        System.out.println(nome + " preso rubinetto");
                        botte.Bevi();
                        System.out.println(nome + " ha bevuto");
                        botte.RilascioRubinetto();
                        System.out.println(nome + " rilasciato rubinetto"); 
                    }         
                }
            } 
            catch(Exception ex) {
               System.out.println("errore " + ex.getMessage());
            }
        }
    }
            

     

  • Definizione dell'oggetto JFBevitori, che implementa la jframe per l'interfaccia grafica.
    Il metodo initComponents è stato omesso.

    package bevitori;
    
    import java.util.ArrayList;
    
    public class JFBevitori extends javax.swing.JFrame {
    
        private ArrayList<Bevitore> lista = new ArrayList<Bevitore>();
        /**
         * Creates new form JFBevitori
         */
        public JFBevitori() {
            initComponents();
        }
    
        private void jbEsciActionPerformed(java.awt.event.ActionEvent evt) {                                       
            System.exit(0);
        }                                      
    
        private void jbAvviaActionPerformed(java.awt.event.ActionEvent evt) {                                        
            Botte b = new Botte(100, 3, this);
            this.jprBotte.setValue(100);
            for(int i=0; i<20; i++) {
                Bevitore bev = new Bevitore("bevitore"+String.valueOf(i), b);
                lista.add(bev);
            }
        }                                       
    
        public void UpdProgressBar() {
            int v = this.jprBotte.getValue()-1;
            System.out.println("progress " + v);
            this.jprBotte.setValue(v);
            this.jprBotte.repaint();
        }
        
        public void Termina() {
            for(int i=0; i<20; i++) {
                lista.get(i).interrupt();
            }        
        }
    }
            

     


© Emanuele Scapin 2009-2014

 

Valid HTML 4.01! Valid CSS!