ciao a tutti... sto dando un esame di java, e ho un problema con questo programma:
vi posto il testo: il file Pesa.java è dato.
Definire in Java quanto richiesto (scrivere nel file Esa.java, tradurre, collegare ed eseguire utilizzando i
comandi indicati nelle avvertenze).
Il file contiene una classe MioThread che estende Thread. Ogni MioThread possiede un numero
proprio num e memorizza il numero proprio di un altro MioThread. Inoltre, ogni MioThread possiede
un array di riferimenti ad altri MioThread. L'elemento i-esimo dell'array contiene un riferimento al
MioThread di numero proprio i. La classe prevede il costruttore MioThread(int num, int succ) e un
metodo setArray(MioThread[] ar). Un MioThread può trovarsi nello stato attivo o disattivo. Il
MioThread che ha num pari a 0 parte nello stato attivo, mentre tutti gli altri partono nello stato
disattivo. Nello stato disattivo, i MioThread si sospendono in attesa si diventare attivi. Un MioThread
attivo stampa la stringa “MioThread num”, attiva il MioThread numero succ (a meno che succ non
valga -1), quindi termina.
Il file contiene, inoltre, la classe Esa, con un metodo fai(int[] arsucc), che crea un MioThread per ogni
elemento dell'array arsucc, con num un numero progressivo a partire da 0 e succ pari al valore
corrispondente nell'array arsucc. Successivamente, il metodo chiama opportunamente setArray su ogni
MioThread creato e, infine, li avvia tutti.codice:// file Esa.java class MioThread extends Thread { private int num; private int succ; private MioThread[] ref; private boolean stato; //true: attivo false: disattivo public MioThread(int num, int succ) { this.num = num; this.succ = succ; this.stato = (num == 0); } public void setArray(MioThread[] ar) { ref = ar; } public synchronized void attiva() { stato = true; notify(); // CON QUESTO FUNZIONA } public synchronized void run() { try{ while(!stato) wait(); Console.scriviStringa("MioThread "+num); }catch(InterruptedException e){ } if(succ!=-1) { ref[succ].attiva(); //notifyAll(); // CON QUESTO NON FUNZIONA } } } class Esa { public void fai(int[] arsucc) { MioThread[] arr = new MioThread[arsucc.length]; for(int i = 0; i<arsucc.length; i++) arr[i] = new MioThread(i, arsucc[i]); for(int i = 0; i<arsucc.length; i++) arr[i].setArray(arr); for(int i = 0; i<arsucc.length; i++) arr[i].start(); } }L'output dovrebbe esserecodice://file Pesa.java class Pesa { public static void main(String[] args) { int[] arsucc = { 2, 3, 1, -1 }; Esa esa = new Esa(); esa.fai(arsucc); } }
Come ho scritto nei commenti, se metto quella notify() nella funzione attiva() funziona (come fa nella soluzione dell'esercizio), mentre se metto, come mi tornerebbe logico, la notifyAll() nel metodo run() ottengo la stampa MioThread 0 e non prosegue.codice:MioThread 0 MioThread 2 MioThread 1 MioThread 3
Non capisco come mai: io ho dei thread bloccati sul wait() nel ciclo che testa il booleano stato. Il thread "MioThread 0" parte (perchè è l'unico con "stato" = true), setta a true "stato" del thread ref[succ]: a questo punto, se facessì notify(), penso, sbloccherei uno a caso fra i thread() bloccati, ma non è detto che sveglierei proprio quello a cui ho settato stato a true, che è l'unico in grado di continuare, quindi ho pensato che fosse giusto mettere notifyAll(). Si svegliano tutti, chi si ritrova stato = true puo' procedere, gli altri tornano sul wait().
Eppure non è così. Potreste spiegarmi come mai la mia soluzione (notifyAll() nel run()) non va bene, e invece quel notify() nella attiva() si?
Grazie a tutti