Visualizzazione dei risultati da 1 a 2 su 2
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2011
    Messaggi
    4

    Problema sincronizzazione thread con LinkedBlockingQueue

    Ciao a tutti io ho questo codice in un oggetto in comune (UfficioPostale) tra due thread Cliente e Impiegato.
    All'avvio faccio scegliere all'utente quanti impiegati ci sono e quanti clienti, ogni cliente effettua delle richieste create a random tra B, E, A e P.
    Il problema è che l'output del tempo medio di attesa non è esatto ovvero:
    codice:
    La media d'attesa per la richiesta B è di: 1242 ms con 23 richieste
    La media d'attesa per la richiesta E è di: -201184639937 ms con 13 richieste
    La media d'attesa per la richiesta A è di: -150888478608 ms con 26 richieste
    La media d'attesa per la richiesta P è di: -217950025263 ms con 18 richieste
    e non riesco a capire perchè, uso delle LinkedBlocingQueue per le code delle richieste e una HashMap per gli impiegati, uso this.clienti per sincronizzare i due thread che è una variabili Condition di accessoVar.
    Se non sono stato molto chiaro domandate pure......

    codice:
    // metodo chiamato dal cliente per mettersi in coda e svegliare un impiegato
        public boolean richiediServizio(Cliente c, int servizio) throws InterruptedException {
            boolean toRet = false;
            // acquisisco il lock
            this.accessoVar.lock();
            try{
                toRet = true;
                    this.clientiAttesa++;
                    this.svegliaImpiegato();
                    switch (servizio)
                    {
                        case 0:
                        {
                            this.contatoreB++;
                            this.println("Inserisco "+c.getName()+" nella coda B");
                            this.tempoB -= System.currentTimeMillis();
                            this.codaB.put(c);
                            this.clienti.signal(); // sveglio un impiegato
                            break;
                        }
                        case 1:
                        {
                            this.contatoreE++;
                            this.println("Inserisco "+c.getName()+" nella coda E");
                            this.tempoE -= System.currentTimeMillis();
                            this.codaE.put(c);
                            this.clienti.signal(); // sveglio un impiegato
                            break;
                        }
                        case 2:
                        {
                            this.contatoreA++;
                            this.println("Inserisco "+c.getName()+" nella coda A");
                            this.tempoA -= System.currentTimeMillis();
                            this.codaA.put(c);
                            this.clienti.signal(); // sveglio un impiegato
                            break;
                        }
                        case 3:
                        {
                            this.contatoreP++;
                            this.println("Inserisco "+c.getName()+" nella coda P");
                            this.tempoP -= System.currentTimeMillis();
                            this.codaP.put(c);
                            this.clienti.signal(); // sveglio un impiegato
                            break;
                        }
                }
            }finally {
                this.accessoVar.unlock();
                return toRet;
            }
        }
    
        // metodo per svegliare un impiegato per servire un cliente in attesa
        private void svegliaImpiegato() throws InterruptedException {
            Impiegato daSvegliare = null;
    
            // acquisisco il lock
            this.accessoVar.lock();
            try{
                if(!this.codaImpiegati.isEmpty()){
                    Set tmpImpiegato = this.codaImpiegati.keySet();
                    Iterator<Impiegato> i = tmpImpiegato.iterator();
                    daSvegliare = i.next();
                    this.codaImpiegati.get(daSvegliare).signal();
                    this.codaImpiegati.remove(daSvegliare);
                    this.println("Svegliato "+daSvegliare.getName());
                    this.serviCliente(daSvegliare);
                }
            }finally {
                this.accessoVar.unlock();
            }
        }
    
        // metodo chiamato dall'impiegato: se ci sono clienti li servi altrimenti sospende la sua esecuzione
        public void serviCliente(Impiegato imp) throws InterruptedException {
            // acqusisco il lock
            this.accessoVar.lock();
            try{
                if(this.clientiAttesa == 0) { // nessun cliente in attesa
                    this.println("Nessun cliente in attesa, metto in coda "+imp.getName());
                    this.codaImpiegati.put(imp, this.accessoVar.newCondition());
                    this.codaImpiegati.get(imp).await();
                    while(this.clientiAttesa == 0)
                        this.clienti.await();
                }else{
                    //seleziono il cliente in attesa da servire
                    this.selezionaCliente(imp);
                }
            }finally {
                this.accessoVar.unlock();
            }
        }
    
        // metodo per selezionare il cliente in attesa da servire in base alla politica di scheduling evitando la starvation
        private void selezionaCliente(Impiegato imp) throws InterruptedException {
            Cliente daServire = null;
            // acquisisco il lock
            this.accessoVar.lock();
            try{
                if((this.codaB.size() > 0) && this.contatore0 < 4) { // dopo 4 richieste B servo una richiesta E
                    this.contatore3 = 0;
                    this.contatore0++;
                    daServire = this.codaB.take();
                    this.tempoB += System.currentTimeMillis();
                    Thread.sleep(50);
                    this.println(imp.getName()+" serve "+daServire.getName()+" con richiesta B");
                    this.clientiAttesa--;
                }else {
                    if((this.codaE.size() > 0) && this.contatore1 < 3) { // dopo 3 richieste E servo una richiesta A
                        this.contatore1++;
                        daServire = this.codaE.take();
                        this.tempoE += System.currentTimeMillis();
                        Thread.sleep(50);
                        this.println(imp.getName()+" serve "+daServire.getName()+" con richiesta E");
                        this.clientiAttesa--;
                    }else {
                        if((this.codaA.size() > 0) && this.contatore2 < 2) { // dopo 2 richieste A servo una richiesta P
                            this.contatore2++;
                            daServire = this.codaA.take();
                            this.tempoA += System.currentTimeMillis();
                            Thread.sleep(50);
                            this.println(imp.getName()+" serve "+daServire.getName()+" con richiesta A");
                            this.clientiAttesa--;
                        }else {
                            if((this.codaP.size() > 0) && this.contatore3 < 1) { // dopo 1 richiesta P servo le richieste B
                                this.contatore0 = 0;
                                this.contatore1 = 0;
                                this.contatore2 = 0;
                                this.contatore3++;
                                daServire = this.codaP.take();
                                this.tempoP += System.currentTimeMillis();
                                Thread.sleep(50);
                                this.println(imp.getName()+" serve "+daServire.getName()+" con richiesta P");
                                this.clientiAttesa--;
                            }else {
                                this.contatore0 = 0;
                                this.contatore1 = 0;
                                this.contatore2 = 0;
                                this.contatore3 = 0;
                            } // END if3
                        } // END if2
                    } // END if1
                } // END if0
            }finally {
                this.accessoVar.unlock();
            }
        }
    }
    EDIT: ecco il progetto così qualcuno magari mi aiuta....
    codice:
    https://docs.google.com/leaf?id=0BzpNxj_qnZgdNGIyY2EzMjctOGZlZC00MWFjLTg2MzQtZWVhMjc2NjRjMzBm&hl=en_US

  2. #2
    Utente di HTML.it
    Registrato dal
    Jun 2011
    Messaggi
    4
    Nessuno che mi aiuti??
    Ovviamente non posso usare il metodo Synchronize............

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.