Visualizzazione dei risultati da 1 a 5 su 5

Hybrid View

  1. #1
    Certamente, hai ragione :
    Qui la spiegazione dell'esercizio.
    Una sala, in grado di ospitare fino a 30 persone, contiene un televisore con 8 canali. La sala è frequentata daun insieme di persone che vi si recano per guardare la TV in compagnia. Ogni persona effettua
    periodicamente le seguenti operazioni:
    1) sceglie a caso il canale C che vuole guardare (con C compreso tra 1 e 8);
    2) entra nella sala; finché la sala è piena, attende in ordine FIFO che si liberi un posto per entrare.
    Dopo essere entrato nella sala:
    · se nessuno sta guardando la TV, cambia il canale su C e prosegue con la visione;
    · se il canale trasmesso è già uguale a C, prosegue con la visione;
    · se infine il canale trasmesso è diverso da C, e qualcuno lo sta guardando, si mette in attesa fino a
    quando il canale diventa uguale a C; al termine dell’attesa prosegue con la visione;
    3) guarda il canale C per un tempo compreso tra 30 e 300 secondi;
    4) esce dalla sala: prima di uscire, se nessuno sta più guardando il canale C, cambia il canale del
    televisore in quello per cui è in attesa il maggior numero di persone.
    Non si tenga conto della possibilità di starvation. Si modellino in Java le persone attraverso dei Thread e si
    implementino due soluzioni che riproducano il funzionamento del problema sopra descritto utilizzando:
    1. la classe Semaphore del package java.util.concurrent
    2. gli strumenti di mutua esclusione e sincronizzazione del package java.util.concurrent.locks.
    Si scriva infine un main d'esempio che, facendo uso di una delle due soluzioni precedenti, inizializzi 100
    Il problema che mi da è che quando fa la wait il Thread, mi solleva una eccezione IllegalMonitorStateException che non riesco a risolvere

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2004
    Messaggi
    99
    Questo giochino è interessante!

    Questo è il mio elaborato, testato (poco) e funzionante!

    Classe Anagraphics:

    codice:
    public class Anagraphics {
    
    
        private static LinkedList<String> anagraphicList =  null;
        private static int minNum = 0;
        private static int maxNum = 100;
        private static Random r = new Random();
        
        private Anagraphics(){  
        }
    
    
        public static String getRandomName(){
            if(anagraphicList == null){
                anagraphicList = new LinkedList<String>();
                anagraphicList.addAll(Arrays.asList(all100Names));
            }   
            int number = r.nextInt(maxNum-minNum) + minNum;
            String name = anagraphicList.get(number);
            anagraphicList.remove(number);
            maxNum--;
            //System.out.println("Rimanenti: " + anagraphicList.size());
            return name;  
        }
    
    
        private static String[] all100Names =    {"mFrancesco","mMarco","mShawn","mAaron","mJonah","mDaniel","mLiam","mRyan","mJames","mAlex"
                ,"mEthan","mAli","mHarry","mMichael","mDavid","mLuke","mMatthew","mJack","mTyler","mJoshua"
                ,"mJordan","mAndrew","mAlexander","mDylan","mNoah","mNiall","mSpencer","mAdam","mJoseph","mZayn"
                ,"mAiden","mNathan","mAustin","mLogan","mJohn","mKevin","mJayden","mBlake","mAnthony","mBrian"
                ,"mChristopher","mJason","mMason","mLouis","mJustin","mWilliam","mJackson","mMax","mBrandon","mKyle",
                "fChloe","fEmily","fIatta","fEmma","fJennifer","fOlivia","fJessica","fHannah","fLily","fSarah"
                ,"fSavannah","fIsabella","fAva","fRebecca","fElla","fSophia","fGrace","fCharlotte","fElizabeth","fMia"
                ,"fAbigail","fSamantha","fAnna","fMegan","fNicole","fAshley","fSophie","fKatie","fZoe","fMadison"
                ,"fLauren","fJasmine","fJade","fAmy","fLucy","fAlyssa","fAmber","fAbby","fAmanda","fBella"
                ,"fNatalie","fLilly","fRachel","fTaylor","fEllie","fAlexis","fPaige","fBarbara","fVanessa","fAlice"};
    
    
    
    
    }

    Classe Channel

    codice:
    public class Channel {
        
        private Channel(){
            
        }
    
    
        private final static int firstChannel = 1;
        private final static int lastChannel = 9;
        private static Random r = new Random();
        
        public static int getChannel(){ 
            int Low = firstChannel;
            int High = lastChannel;
            return r.nextInt(High-Low) + Low; 
        } 
    }

    Classe OpenTVRoom (<--KickStart Class)

    codice:
    public class OpenTvRoom {
        
        private static final int totPersons = 100;//Ovviamente non > al no. nomi disponibili nella classe Anagraphics!
        
        public static void main(String[] args) throws InterruptedException {
            
            ExecutorService personQueueThreads = Executors.newCachedThreadPool(); 
            
            Set<Callable<String>> personsTasks = new HashSet<Callable<String>>();
            for(int i = 0; i<totPersons; i++){
                personsTasks.add(new Person(Anagraphics.getRandomName(),Channel.getChannel())); 
            }
            
            System.out.println("Tutti a vedere la TV!");
            personQueueThreads.invokeAll(personsTasks);
            
            personQueueThreads.shutdown();
            personQueueThreads.awaitTermination(1, TimeUnit.HOURS);
            
            System.out.println("\r\n======== SALA TV CHIUSA :_(( ========\r\n");
        }
    
    
    }

    Classe Person

    codice:
    public class Person implements Callable<String> {
        
        public Person(String personName, int channel){
            this.personName = personName.substring(1,personName.length());
            this.Sex = (personName.startsWith("m")?"Maschio":"Femmina");
            this.channel = channel; 
             
        }
        
    //    public Lock lockPerson = new ReentrantLock();
    //    public Condition iWantMyChannelCondition = lockPerson.newCondition();
     
        //variabili
        private int channel = 0;
        private String personName = "";
        private String Sex = null;//!!!! Nascono tutti angeli insomma (^ - ^) 
         
        //thread run method
        public String call() throws Exception {
             
            TvRoom.getEntranceTvRoom().watchTV(this);
            return this.personName + " è uscito dalla sala!";
        }
        
        //Getters, Setters
        public String getSex() {
            return Sex;
        }
    
    
        public void setSex(String sex) {
            Sex = sex;
        }
        
        public int getChannel() {
            return channel;
        }
    
    
        public void setChannel(int channel) {
            this.channel = channel;
        }
    
    
        public String getPersonName() {
            return personName;
        }
    
    
        public void setPersonName(String personName) {
            this.personName = personName;
        } 
    }

    Classe Time

    codice:
    public class Time {
        private Time(){
            
        }
    
    
        private final static int minTime = 3000;
        private final static int maxTime = 30000;
        private static Random r = new Random();
        
        public static int getRandomWatchTime(){  
            return r.nextInt(maxTime-minTime) + minTime; 
        } 
    }
    Classe TvRoom

    codice:
    public class TvRoom { 
        private final int waitingQueue = 20; 
        private final Map<Integer,Integer> channelDesiredMap = new HashMap<Integer,Integer>(1000); 
        private static TvRoom instanceTvRoom = new TvRoom();
        private final static int maxPersonRoomCapacity = 30;
        private final Lock lock = new ReentrantLock(); 
        private final Lock lockExit = new ReentrantLock(); 
        private final Condition iWantMyChannelCondition = lock.newCondition(); 
        private int tvWatchers = 0;
        private int currentChannel = 0; //Canale inesistente..validi da 1 a 8
    
    
        private int getFirstMaxDesiredChannel(){
            Map.Entry<Integer,Integer> maxEntry = null;
    
    
            for (Map.Entry<Integer,Integer> entry : channelDesiredMap.entrySet())
            {
                if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
                {
                    maxEntry = entry;
                }
            }
            System.out.println("Il Canale più desiderato è : " + maxEntry.getKey());
            return maxEntry.getKey();
        }
    
    
        private boolean getCurrentFavouriteChannelViewers(Map<Integer,Integer> map,int favChannel){
             return( map.get(favChannel) >0?true:false);
        }
    
    
        private void incrementCount(Map<Integer,Integer> map,Integer q) { 
            Integer oldVal, newVal; 
            oldVal = map.get(q);
            newVal = (oldVal == null) ? 1 : (oldVal + 1);
            map.put(q, newVal); 
        }
    
    
        private void decrementCount(Map<Integer,Integer> map,Integer q) { 
            Integer oldVal, newVal; 
            oldVal = map.get(q);
            newVal = (oldVal == null) ? 0 : (oldVal - 1);
            map.put(q, newVal); 
        }
    
    
        public boolean getCurrentChannelEquality(int favChannel) {
            boolean bool = false; 
            //System.out.println("canale corrente: " + this.currentChannel + " fav: " + favChannel);
            if(this.currentChannel == favChannel)
                bool = true; 
            return bool;
        }
    
    
        private void trySetCurrentChannel2Favourite(Person person){ 
            if(getTvWatchers()==1){
                this.currentChannel = person.getChannel(); 
                System.out.println(person.getPersonName() + " sintonizza il Canale " + person.getChannel() 
                        + " xkè sta guardando solo " + (person.getSex().equalsIgnoreCase("maschio")?"lui":"lei")  +"!");
            }
             
                incrementCount(channelDesiredMap,person.getChannel());
             
        }
    
    
        private void observeTvScreen(){ 
            tvWatchers++; 
        }
    
    
        public int getTvWatchers() { 
            return tvWatchers;
        }
    
    
        private void quitWatching(){ 
            tvWatchers--; 
        }
    
    
        private TvRoom(){ 
            System.out.println("\r\n======== SALA TV APERTA :-)) ========\r\n");
        }
    
    
        private static Semaphore semaphore = new Semaphore(maxPersonRoomCapacity, true);
    
    
        public static TvRoom getEntranceTvRoom(){
            return instanceTvRoom;
        }
    
    
        public void watchTV(Person person){
    
    
            try {
                semaphore.acquire();
            } catch (InterruptedException e1) { 
                e1.printStackTrace();
            }
            try {
                attemptWatchTV(person);
            } finally { 
                /*
                 *  esce dalla sala: prima di uscire, se nessuno sta più guardando il canale C,
                 *   cambia il canale del 
                 *   televisore in quello per cui è in attesa il maggior numero di persone.
                 */
                lockExit.lock();
                System.out.println(person.getPersonName()
                        + " è uscit" + (person.getSex().equalsIgnoreCase("maschio")?"o":"a") +" dalla sala!");
                /* */
     
                decrementCount(channelDesiredMap,person.getChannel());
             
                if(!getCurrentFavouriteChannelViewers(channelDesiredMap,person.getChannel())){ 
                    this.currentChannel = getFirstMaxDesiredChannel(); 
                    System.out.println("\"Accidenti! Pare che nessuno sia più interessato al mio Canale preferito...\" disse "
                            + person.getPersonName() + " prima di sintonizzare la TV sul nuovo Canale " + this.currentChannel);
                }
                 
                quitWatching();
                System.out.println("Rumore della porta che si chiude dietro a " + person.getPersonName());
                lockExit.unlock();
                semaphore.release();
            } 
    
    
        }
    
    
        public void attemptWatchTV(Person person){ 
            try {
                System.out.println(person.getPersonName() +" (" + person.getSex()+ ") entra in sala TV (actual tot." + (maxPersonRoomCapacity-semaphore.availablePermits())+ " p.) e vuol vedere il Canale: " + person.getChannel());
                lock.lock();
                observeTvScreen(); 
                //Tento di settare il canale C
                trySetCurrentChannel2Favourite(person); 
                //Check se è il mio canale preferito  C
                while(!getCurrentChannelEquality(person.getChannel())){ 
                    System.out.println(person.getPersonName() + " attende il Canale " + person.getChannel() + " per " + this.waitingQueue + " secondi...mentre vede Canale " + this.currentChannel ); 
                    iWantMyChannelCondition.await(this.waitingQueue, TimeUnit.SECONDS); 
                }
                iWantMyChannelCondition.signalAll(); 
                lock.unlock();
    
    
                System.out.println(person.getPersonName() + " guarda il suo canale preferito alla TV!!");
                //Fisso la TV! 
                //guardo il canale C per un tempo compreso tra 30 e 300 secondi; 
                Thread.sleep(Time.getRandomWatchTime());   
            } catch (InterruptedException e) { 
                e.printStackTrace();
            } 
        } 
    }

    Oddio l'ultima classe è un'obbrobrio...spero non la veda chi dico io...

    In fondo si tratta di un'esercizio, lascio a te i seguenti e doverosi allineamenti con la traccia:
    - Implementare con i Thread e non i Callable
    - Gestione differenziata di due esercizi che tengano conto singolarmente dell'utilizzo di Semaphore e degli oggetti del java.util.concurrent.locks.
    -
    Aggiusta i valori di attesa negli estremi della classe Time perchè aspettare da 30 a 300 secondi è na pizza...(e a me piace la pizza!).

    Oltretutto mi pare ci sia altro, l ultimo periodo è troncato, cmq...
    Ah: la prox volta se hai uno stackTrace, sottoponi la parte interessante, con la sola classe d'eccezione ci si fa poco...

    Buon Divertimento
    Ultima modifica di Gatsu78; 25-04-2015 a 21:08
    se mi chiedeste chi è per me un vero amico vi risponderei che è una persona che io considero alla pari di me.

  3. #3
    Scusami, mi ero totalmente dimenticato , ho risolto, semplicemente mi è bastato sostituire il metodo TimeUnit.SECONDS.wait() con Thread.sleep() , ora va tutto a meraviglia, semplicemente quel metodo va usato solo in blocchi Synchronized, io pensavo si potesse usare sincronizzando... Grazie lo stesso

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.