Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    230

    [java] thread consumatori e produttori.

    Ciao a tutti,
    Il programma che segue è molto banale tuttavia non riesco a capire alcune cose.
    Il programma ha l'obbiettivo di creare 4 produttori (ProducerThread) e 3 consumatori ConsumerThread, i loro accessi alla risorsa comune BufferMonitor è realizzato un "monitor".
    Riporto il codice e poi la mia domanda

    Codice PHP:
    public class BufferMonitor {
        private 
    int value;
        
    boolean empty;
        public 
    BufferMonitor(){
            
    value=10000;
            empty=
    true;
        }
        public 
    synchronized void putBuffer(int i){
            while(
    emptyBuffer()==false){ //buffer is full
                
    try {
                    
    wait();
                    
    System.out.print("Producer waiting \n");
                    
                    } catch (
    InterruptedException e) {
                    
    System.out.print(e);
                }
            }
            
    value=i;
            empty=
    false;
            
    notifyAll();
        }
        public 
    synchronized int getBuffer(){
            
    System.out.print("getBuffer afther "+value +"\n");
            while (
    emptyBuffer()==true){ //buffer is empty
                
    try{
                    
    wait();
                    
    System.out.print("Consumer waiting \n");
                    
                }catch(
    InterruptedException e){
                    
    System.out.print(e);
                }
            }
            
    System.out.print("getBuffer before "+value +"\n");
            empty=
    true;
            
    notifyAll();        
            return 
    value;
        }
        public 
    boolean emptyBuffer(){
            return empty;
        }


  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    230
    Codice PHP:
    public class ProducerThread extends Thread{
        private 
    BufferMonitor b;
        private 
    int i;
        public 
    ProducerThread (BufferMonitor bint m){        
            
    this.b=b;
            
    i=m;
        }
         public 
    void run(){
                
    b.putBuffer(i);
                
    System.out.print(Thread.currentThread()+ " writing " +i"\n");
                
            
        }
    }



    public class 
    ConsumerThread extends Thread {
        private 
    BufferMonitor b;
            
        public 
    ConsumerThread(BufferMonitor b){
            
    this.b=b;
        }
        public 
    void run(){
            
    System.out.print(Thread.currentThread()+" get"b.getBuffer());
                            
        }
    }

    public class 
    MonitorTester {

        
    /**
         * @param args
         */
        
    public static void main(String[] args) {
            
    BufferMonitor b=new BufferMonitor();
            
    // TODO Auto-generated method stub
            
    ProducerThread[]p=new ProducerThread[4];
            
    ConsumerThread[]c=new ConsumerThread[3];
            for (
    int i=0i<4;i++){
            
    p[i]=new ProducerThread(b,i);
            
    p[i].setName("Producer "+i);
            try {
                
    p[i].join();
            } catch (
    InterruptedException e) {
                
    // TODO Auto-generated catch block
                
    System.out.print(e);
                }
            
    p[i].start();
            }

            for (
    int i=0i<3;i++){
                
    c[i]=new ConsumerThread(b);
                
    c[i].setName("Consumer "+);
                try{
                    
    c[i].join();
                }catch (
    InterruptedException e){
                    
    System.out.print(e);
                }
                
    c[i].start();
                
            }
            
        }        


  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    230
    Quando eseguo il programma (ripoto solo una parte dell'output) ottengo:
    1 Thread[Producer 0,5,main] writing 0
    2 getBuffer afther 0
    3 getBuffer before 0
    4 Producer waiting
    5 Thread[Producer 3,5,main] writing 3
    6 Producer waiting
    7 Producer waiting
    8 Thread[Consumer 0,5,main] get0
    9 getBuffer afther 3
    10 getBuffer before 3
    ...

    Allora si avvia il primo produttore scrive 0, poi (rihe 2,3) viene chiamto il consumatore perchè altrimenti il produttore alla riga 5 non potrebbe scrivere e così via.
    il problema è che solo alla linea 8 viene stampato che il cosumatore ha prelevato
    dal buffer il valore 0 se pur lo ha fatto alle linee 2 e 3.
    L'output che mi sarei aspettato sarebbe stato:
    1 Thread[Producer 0,5,main] writing 0
    2 getBuffer afther 0
    3 getBuffer before 0
    4 Thread[Consumer 0,5,main] get0
    5 Producer waiting
    6Thread[Producer 3,5,main] writing 3
    ...

    Cosa c'è che non va?

  4. #4
    L'ordine delle stampe non è strano; dipende dal fatto che l'istruzione:

    codice:
    System.out.println(Thread.currentThread() + " get " + b.getBuffer());
    determina l'esecuzione di b.getBuffer(), che, prima di ritornare, sveglia gli altri thread con la notifyAll().
    Per verificarlo, puoi provare a togliere la notifyAll() dal metodo getBuffer, e modificare il run() del consumer in questo modo:

    codice:
    synchronized (b)
    {
      System.out.println(Thread.currentThread() + " get " + b.getBuffer());
      b.notifyAll();			
    }
    Così gli altri thread vengono svegliati solo dopo la stampa.

    Ciao,

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    103

    per fortuna che c'è questo forum

    ragazzi non ci crederete ma ho capito sui thread più con questo esempio che con le lezioni in classe.
    Quindi prima di tutto un grazie.
    Poi scusate la domanda che vi sembrerà stupida, ma è la linea di codice

    System.out.print(Thread.currentThread()+ " writing " +i+ "\n");
    che produce:

    Thread[Producer 0,5,main] writing 0
    e cioè che significa?
    Che il Thread è stato attivato dalla classe main, il Produttore è lo 0 di 5 che sta scrivendo sul buffer?

  6. #6
    Se leggi il javadoc del metodo toString() di Thread, ti dice:

    codice:
    public String toString()
    Returns a string representation of this thread, including the thread's name, priority, and thread group.
    
    Overrides:
    toString in class Object
    Quindi, 'Produttore 0' è il nome del thread (assegnato dal programma), 5 è la priorità (corrispondente a Thread.NORM_PRIORITY), e 'main' è il gruppo a cui appartiene il thread.

    Ciao,

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    103
    capito!
    La priorità ho visto che può essere cambiata però non c'è scritto se impostandola a un valore più basso (ad esempio 0) vuol dire che ha maggiore priorità o minore.

    Inoltre non ho capito il problema che si faceva puntino...ho fatto le tue modifiche al codice e in effetti l'output cambia nel senso che dicevi tu. Ma qual'era il problema del primo output?

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    103
    si finalmente sono riuscita a capire qlc dal sito della sun (può essere utile!!)

    java.sun.com/j2se/1.4.2/docs/api/

    ecco che c'è scritto sulle priorità

    public static final int MAX_PRIORITY 10
    public static final int MIN_PRIORITY 1
    public static final int NORM_PRIORITY 5

    perciò la risposta alla mia prima domanda è che 10 è il massimo della priorità che si può dare a un thread!!

    Però ora resta da capire qual'era il problema che si faceva puntino sul primo output...io sto provando a simulare su carta cosa fa il compilatore ma non mi è molto chiaro...

  9. #9
    Utente di HTML.it L'avatar di nether
    Registrato dal
    Dec 2006
    Messaggi
    376
    Però ora resta da capire qual'era il problema che si faceva puntino sul primo output...io sto provando a simulare su carta cosa fa il compilatore ma non mi è molto chiaro...
    Il problema era che si aspettava di leggere i messaggi in un ordine diverso rispetto al quale effettivamente apparivano: nel suo codice le operazioni seguivano un certo ordine, che non era effettivamente rispecchiato dall'ordine con cui venivano stampati in console i messaggi.

  10. #10
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    103
    infatti probabilmente Io non ho capito bene il funzionamento dei Thread perciò non mi posso rendere conto del problema.
    Non riesco a capire la sequenza dei passi che fa il compilatore.
    Nel main, nel ciclo for oltre a creare istanze di Produttori, lanciando anche start non dovrebbe riempirsi tutto il buffer con i 5 valori visto che nel run dei Produttori c'è invocato putBuffer(i) ?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.