Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315

    Thread: utilizzo wait() e notify()

    Rivedendo un po' di concetti mi sono imbattuto in un esercizio sui thread dove viene richiesto di astrarre il concetto di corsa. All'interno, oltre alla classe del main e a quella che rappresenta il thread del corridore, bisogna definire anche una classe Giudice che definisce un thread che deve partire nel momento in cui parte la corsa e rimanere in attesa fino a che il primo corridore raggiunge il traguardo, a quel punto deve stampare un messaggio esplicativo.
    Ho sincronizzato quindi i metodi run del corridore e del giudice e ho utilizzato wait() e notify() ma il problema è che il giudice non viene mai "risvegliato" dal suo stato di attesa anche dopo aver chiamato notify().
    Vi posto il codice incriminato:

    classe Runner
    codice:
    package thread;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Runner implements Runnable {
    
        static List<String> ordineArrivo = new ArrayList<>();
        
        public Runner(String nome) {
            Thread runner = new Thread(this, nome);
            runner.setName(nome);
            runner.start();
        }
        
        
        @Override
        public synchronized void run() {
            for(int i=0; i<=10; i++) {
                long attesa;
                try {
                    double numero = (Math.random()*1000)+500;
                    attesa = (long) numero ;
                    Thread.sleep(attesa);
                }
                catch(InterruptedException exc) {
                    exc.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " " + i*10 + "m");
            }
            System.out.println(Thread.currentThread().getName() + " arrivato");
            ordineArrivo.add(Thread.currentThread().getName());
            notify();
        }
        
        
        public static List<String> getLista() {
            return ordineArrivo;
        }
    }

    classe Giudice:
    codice:
    package thread;
    
    public class Giudice implements Runnable {
        
        protected static boolean primoArrivato = false;
        
        public Giudice() {
            Thread giudice = new Thread(this);
            giudice.start();
        }
        
        @Override
        public synchronized void run() {
            System.out.println("giudice presente");
            while (primoArrivato == false) {
                try {
                    wait();
                } catch (InterruptedException exc) {
                    exc.printStackTrace();
                }
                primoArrivato = true;
            }
            System.out.println("il primo è arrivato");
           }
    }

    Dove sbaglio?

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2004
    Messaggi
    99
    mmm....sai io non farei così.

    E' cmq un argomento interessante perchè non ho mai fatto una cosa simile...

    Guarda se ti torna, poi lascio il parere ai + esperti

    classe principale (nome omaggio alla vecchia gloria MSX!)

    codice:
    public class AthleticLand    { 
        private static String[] corridori = {"Pippo","Pluto","Paperino" ,"Marco Cocco", "Topolino","Minnie", "Francesco Muià"};
        
        public static final CyclicBarrier startLine = new CyclicBarrier(corridori.length);
        
        private static boolean winner = false;
        
        final static long LOWER_RANGE = 0; 
        final static long UPPER_RANGE = 1000;
        
        public static long getRandomWait(){
     
            Random random = new Random();
    
    
            return  LOWER_RANGE + (long)(random.nextDouble()*(UPPER_RANGE - LOWER_RANGE));
        }
        
        public static void main(String[] args)   {
    
    
            ExecutorService executorServiceJudge = Executors.newFixedThreadPool(corridori.length);
    
    
            Set<Callable<String[]>> callables = new HashSet<Callable<String[]>>();
    
    
            for(int a = 0; a <corridori.length; a++){
                callables.add(new Corridore(corridori[a]));
            }
    
    
            List<Future<String[]>> futures = null;
    
    
            System.out.println("\r\n===========Prontiiii...via!==========\r\n");
    
    
            try {
                futures = executorServiceJudge.invokeAll(callables);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            Map mappa = new HashMap<String, Long>();
            for(Future<String[]> future : futures){
                try { 
                    mappa.put(future.get()[1], Long.parseLong(future.get()[0]));
                    // ti interessa solo il primo...
                } catch (ExecutionException e) { 
                    e.printStackTrace();
                } catch (InterruptedException e) { 
                    e.printStackTrace();
                }
            }
    
    
            executorServiceJudge.shutdown();
              sortByValue(mappa);
             
        }
    
    
        public static synchronized void Giudice (String name) {
            if(!winner){
                System.out.println(" \r\n-------- Il vincitore è : " + name);
                winner= true;
            } 
        }
    
    
        public static void sortByValue(Map unsortMap) {     
            List list = new LinkedList(unsortMap.entrySet());
    
    
            Collections.sort(list, new Comparator() {
                public int compare(Object o1, Object o2) {
                    return ((Comparable) ((Map.Entry) (o1)).getValue())
                            .compareTo(((Map.Entry) (o2)).getValue());
                }
            });
    
    
            Map sortedMap = new LinkedHashMap();
            for (Iterator it = list.iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                sortedMap.put(entry.getKey(), entry.getValue());
            }
            
            Iterator it  = sortedMap.entrySet().iterator();
            System.out.println("\r\n=========== Traguardi !!!==========\r\n");
            while(it.hasNext()){
                Map.Entry entry = (Map.Entry) it.next();
                System.out.println(entry.getKey() + " " + entry.getValue());
            }
        }
    }


    e il corridore tipico:



    codice:
    public class Corridore implements Callable{
    
        private long durataCorsa = 0;
        private String name = null;
        
        public Corridore (  String name){ 
            this.durataCorsa =AthleticLand. getRandomWait();
            this.name = name;
            System.out.println("Corridore: " + name + " pronto alla linea di partenza! ci metterà-->" + durataCorsa);
        }
        
        @Override
        public Object call() throws Exception {
            AthleticLand.startLine.await();
            System.out.println(name +" partito!");
            Thread.sleep(durataCorsa*10);
            AthleticLand.Giudice(name);
            return new String[]{System.currentTimeMillis()+"", name};
        }
    
    
    }


    Forse il risultato ancor + preciso si avrebbe sfruttando la differenza temporale data dall'effettivo start dello sleep del corridore e la restituzione del future relativo...tuttavia con il CyclicBarrier dovrei aver reso abbastanza bene l'idea...
    Ultima modifica di Gatsu78; 25-02-2015 a 15:54
    se mi chiedeste chi è per me un vero amico vi risponderei che è una persona che io considero alla pari di me.

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Ho letto il tuo codice, premetto che sicuramente il mio codice non va preso da esempio, ma non si potevano fare le stesse cose senza utilizzare pool di thread, CyclicBarrier e tutte quelle collection?

  4. #4
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    nessuno interviene?

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Mentre rivedevo alcuni esercizi sui thread mi sono imbattuto in un problema e cioè nella IllegalMonitorStateException.
    Vi posto un po' di codice perchè vorrei chiarirmi questo dubbio.
    Allora, io ho un'applicazione che permette di effettuare degli acquisti e ogni volta che si decide di effettuare un acquisto (dei souvenir) mi crea un thread in questo modo:
    codice:
    private void nuovoAcquisto() {
        AttivitaPrincipale attivitaPrincipale = new AttivitaPrincipale();
        Thread t = new Thread(attivitaPrincipale);
        t.start();
      }
    All'interno del suo metodo run() ci sono delle if per poter selezionare il tipo di souvenir acquistato, ad esempio questo è l'if per i magneti:
    codice:
    public synchronized void run() {
        if (eseguita)
          return;
        eseguita = true;
        
        // Chiedi tipo souvenir
        tipoAcquisti = AttivitaIO.chiediTipoSouvenir();
    
        CreaNuovoScontrino creaScontrino = new CreaNuovoScontrino();
        Executor.perform(creaScontrino);
        scontrinoCorrente = creaScontrino.getRisultato();
    
        Thread sottoRamoMagneti = null;
        Thread sottoRamoBerretti = null;
    
        if (tipoAcquisti.isMagneti()) {
          sottoRamoMagneti = new Thread(new AttivitaSottoramoMagneti(scontrinoCorrente));
          sottoRamoMagneti.start();
          try {
              Thread.currentThread().wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
       ...
    }
    l'eccezione viene sollevata nel momento in cui invoco il metodo wait() sul thread corrente perchè in realtà non ho il monitor di quell'oggetto, ma come è possibile questa cosa? cioè come faccio a non avere il monitor di un thread in esecuzione?

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.