Innanzitutto la stampa del main la fa comunque e praticamente subito. Il main() è velocissimo, termina quasi istantaneamente. Ma la istanza della JVM NON termina subito, perché ci sono gli altri 2 thread avviati.
Buongiorno, chiedo scusa se ti cito nuovamente dopo aver risolto il problema di ieri, ma non capisco una cosa. Premetto di aver letto sul forum la spiegazione che hai dato riguardo wait() notify() run(), ed ho capito che, bene o male, dopo aver usato start() il metodo run non inizia subito, nel caso specifico ho visto che dopo start() il controllo passa al Thread principale e poi ai vari metodi run(). Quello che non capivo è quali fossero i vari passaggi dentro al codice, quindi ho inserito un paio di println per capire come si muovesse il tutto. Quello che ne è uscito è un output sempre diverso: ho visto che i vari cicli while non sempre vengono fatti partire subito, certe volte dopo 1 o 2 cicli completi di put()/get(), altre volte dopo più di 20 cicli, come mai? Altra cosa, ho visto che, dopo aver completato un metodo synchronized (senza però essere essere entrato nel ciclo while corrispondente e, quindi, senza aver fatto una chiamata a wait() ) il controllo passa comunque al Thread successivo, mi chiedo quindi, se togliessi il notify() e il wait(),o anche solo il wait(), ci sarebbe comunque questa alternanza tra i due Thread? Ti ringrazio e mi scuso per il disturbo. Allego il codice con i vari controlli e un output del codice.
package pc;
class Q{
int n;
boolean valueSet = false;
synchronized int get(){
System.out.println("punto 1");
while(!valueSet){
System.out.println("punto 2");
try{
System.out.println("punto 3");
wait();
}catch(InterruptedException e){
System.out.println("InterruptedException intercettata");
}
}
System.out.println("punto 4");
System.out.println("Ottenuto: " +n);
valueSet = false;
System.out.println("punto 5");
notify();
System.out.println("punto 6");
return n;
}
synchronized void put(int n){
System.out.println("punto 7");
while(valueSet){
System.out.println("punto 8");
try{
System.out.println("punto 9");
wait();
} catch(InterruptedException e){
System.out.println("InterruptedException intercettata");
}
}
System.out.println("punto 10");
this.n = n;
valueSet = true;
System.out.println("Inserito: " +n);
System.out.println("punto 11");
notify();
System.out.println("punto 12");
}
}
class Producer implements Runnable{
Q q;
Producer(Q q){
System.out.println("punto 13");
this.q = q;
new Thread(this, "Producer").start();
System.out.println("punto 14");
}
public void run(){
System.out.println("punto 15");
int i = 0;
while(true){
System.out.println("punto 16");
q.put(i++);
System.out.println("punto 17");
}
}
}
class Consumer implements Runnable{
Q q;
Consumer(Q q){
System.out.println("punto 18");
this.q = q;
new Thread(this, "Consumer").start();
System.out.println("punto 19");
}
public void run(){
System.out.println("punto 20");
while(true){
System.out.println("punto 21");
q.get();
System.out.println("punto 22");
}
}
}
public class PC {
public static void main(String[] args) {
Q q = new Q();
System.out.println("punto 23");
new Producer(q);
System.out.println("punto 24");
new Consumer(q);
System.out.println("punto 25");
System.out.println("Premere Ctrl+C per fermare");
}
}
OUTPUT:
punto 23
punto 13
punto 14
punto 24
punto 15
punto 18
punto 16
punto 7
punto 10
punto 19
punto 25
Premere Ctrl+C per fermare
punto 20
punto 21
Inserito: 0
punto 11
punto 12
punto 17
punto 16
punto 1
punto 4
Ottenuto: 0
punto 5
punto 6
punto 7
punto 10
punto 22
punto 21
Inserito: 1
punto 11
punto 12
punto 17
punto 16
punto 1
punto 4
Ottenuto: 1
punto 5
punto 6
punto 22
punto 21
punto 7
punto 10
Inserito: 2
punto 11
punto 12
punto 17
punto 16
punto 7
punto 8 // prima volta che entra dentro al while nel metodo put()
punto 9
punto 1
punto 4
Ottenuto: 2
punto 5
punto 6
punto 22
punto 21
punto 10
Inserito: 3