 |
AppletTalk.com Java discussions newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Will Guest
|
Posted: Tue Apr 25, 2006 2:12 pm Post subject: Sleep in Java? |
|
|
Scusatemi avrei bisogno di una semplice funzione che mi permetta di
fermare l'esecuzione per un periodo di tempo. In C utilizzo la sleep, in
java? Ho trovato Thread.sleep(period) ma non sempre funzionare gran chè
bene...qualche alternativa?
Grazie mille! |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 3:12 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 15:59:29 +0200, Will ha scritto:
| Quote: | Scusatemi avrei bisogno di una semplice funzione che mi permetta di
fermare l'esecuzione per un periodo di tempo. In C utilizzo la sleep, in
java? Ho trovato Thread.sleep(period) ma non sempre funzionare gran chè
bene...qualche alternativa?
Grazie mille!
|
scusa perchè non dovrebbe funzionare bene? è l'unica standard
che problema ti da?
(ps... ricordati sempre di catturare InterruptedException)
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 3:12 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 16:50:20 +0200, Will ha scritto:
| Quote: | OcchioDiDrago wrote:
scusa perchè non dovrebbe funzionare bene? è l'unica standard
che problema ti da?
(ps... ricordati sempre di catturare InterruptedException)
Ma forse funziona anche, solo che lo sto utilizzando all'interno di un
programma grafico (fatto le le swing) e sono abbastanza niubbo di java e
sembra che al posto di stampare i valori ogni qual volta scade lo sleep,
li stampa tutti insieme alla fine, dopo che ha aspettato il tempo.
Forse devo in qualche modo utilizzare sleep accoppiato a qualche
funzione di paint?
|
MAI - MAI - MAI e ripeto
*MAI*
fermare e/o rallentare il thread di gestione degli eventi Swing/AWT!!!!!!!
Ottieni esattamente l'effetto che hai descritto.
Quello che devi fare è
1) raggruppare tutta la sequenza che comprende gli "sleep" in un solo
metodo, che chiamerai ad esempio eseguiLavoroLungo()
2) creare un thread che andrà a richiamare questo metodo
3) dal tuo metodo, quando devi aggiornare la gui, fallo usando
javax.swing.SwingUtilites.invokeLater() - leggi la documentazione per
maggiori info
4) Studia meglio come funziona Swing, prima di fare cose che siano più
complesse di un get/set di proprietà *immediata* in risposta agli eventi
se serve una mano in più, posta direttamente il codice incriminato e vediamo
di correggerlo.
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
Will Guest
|
Posted: Tue Apr 25, 2006 3:12 pm Post subject: Re: Sleep in Java? |
|
|
OcchioDiDrago wrote:
| Quote: | scusa perchè non dovrebbe funzionare bene? è l'unica standard
che problema ti da?
(ps... ricordati sempre di catturare InterruptedException)
|
Ma forse funziona anche, solo che lo sto utilizzando all'interno di un
programma grafico (fatto le le swing) e sono abbastanza niubbo di java e
sembra che al posto di stampare i valori ogni qual volta scade lo sleep,
li stampa tutti insieme alla fine, dopo che ha aspettato il tempo.
Forse devo in qualche modo utilizzare sleep accoppiato a qualche
funzione di paint? |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 4:13 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 17:48:48 +0200, OcchioDiDrago ha scritto:
| Quote: | Il Tue, 25 Apr 2006 17:20:47 +0200, Will ha scritto:
Praticamente ci sono 2 bottoni e 3 label. I bottoni sono Start e Stop.
Quando premo su Start dovrebbe iniziare a cambiare la il text delle
label seguendo un ritmo (che è scandito da sleep(100)). Quando premo su
Stop poi il tutto dobrebbe fermarsi.
Intanto vedo di recuperare informazioni sui punti 1, 2, 3 e 4 :)
Vai tranquillo, dovrebbe bastare. Ti faccio uno "schema modello" a cui
dovrai adattare il resto, così non dovresti più avere blocchi.
|
....
public void actionPerformed(ActionEvent e) {
if (e.getSource()==Start) {
if (!bstart) bstart=false; else bstart=true;
if (bstart) {
Thread numeraThread=new Thread(new Runnable () {
public void run() {numeraCiclo();}
});
numeraThread.start();
}
}
if (e.getSource()==Stop) {
bstart=false;
}
}
private void numeraCiclo() {
while (bstart) {
//Questo "sleep" non blocca il thread di gestione degli
//eventi
try {Thread.sleep(100);} catch (InterruptedException ex) {}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Qui puoi interagire con il thread di gestione degli
//eventi, invokeLater è stato creato apposta per questo
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
});
iter++;
if (iter>100) {iter=0;break;}
}
}
....
Ho approfittato del fatto che usi una variabile booleana a livello di classe
(bstart) per indicare se il ciclo deve girare o meno. Complimenti (sinceri),
hai pensato all'elaborazione parallela prima ancora di pensare ai Thread!!!
Questo infatti è il metodo più comune (diciamo anche l'unico) per
interrompere l'elaborazione di un Thread senza usare Thread.stop() (che è
deprecato).
Una piccola nota: visto l'uso che fai di bstart, ti conviene dichiararla
come
private volatile boolean bstart;
Questo impedisce al compilatore di ottimizzarla, evitando il rischio di
ottenere valori sfalsati (se ottimizzata, potrebbe capitare che un suo
assegnamento non venga eseguito)
In bocca al lupo!!!
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
Will Guest
|
Posted: Tue Apr 25, 2006 4:13 pm Post subject: Re: Sleep in Java? |
|
|
OcchioDiDrago wrote:
| Quote: | MAI - MAI - MAI e ripeto
*MAI*
fermare e/o rallentare il thread di gestione degli eventi Swing/AWT!!!!!!!
Ottieni esattamente l'effetto che hai descritto.
Quello che devi fare è
1) raggruppare tutta la sequenza che comprende gli "sleep" in un solo
metodo, che chiamerai ad esempio eseguiLavoroLungo()
2) creare un thread che andrà a richiamare questo metodo
3) dal tuo metodo, quando devi aggiornare la gui, fallo usando
javax.swing.SwingUtilites.invokeLater() - leggi la documentazione per
maggiori info
4) Studia meglio come funziona Swing, prima di fare cose che siano più
complesse di un get/set di proprietà *immediata* in risposta agli eventi
se serve una mano in più, posta direttamente il codice incriminato e vediamo
di correggerlo.
|
Allora innanzitutto grazie mille per la disponibilità.
Il codice (non tutto perchè è abbastanza lungo) è il seguente:
public void actionPerformed(ActionEvent e) {
if(e.getSource() == Start) {
if(bstart == true) bstart = false;
else bstart = true;
if(bstart == true){
while(bstart == true){
repaint();
numera();
repaint();
iter++;
if(iter > 100){
iter = 0;
break;
}
}
}
}
if(e.getSource() == Stop){
bstart = false;
}
}
private void numera(){
try{
Thread.sleep(100);
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
catch(InterruptedException e){
System.out.println("Sleep Interrupted");
}
}
Praticamente ci sono 2 bottoni e 3 label. I bottoni sono Start e Stop.
Quando premo su Start dovrebbe iniziare a cambiare la il text delle
label seguendo un ritmo (che è scandito da sleep(100)). Quando premo su
Stop poi il tutto dobrebbe fermarsi.
Intanto vedo di recuperare informazioni sui punti 1, 2, 3 e 4  |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 4:13 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 17:20:47 +0200, Will ha scritto:
| Quote: | Praticamente ci sono 2 bottoni e 3 label. I bottoni sono Start e Stop.
Quando premo su Start dovrebbe iniziare a cambiare la il text delle
label seguendo un ritmo (che è scandito da sleep(100)). Quando premo su
Stop poi il tutto dobrebbe fermarsi.
Intanto vedo di recuperare informazioni sui punti 1, 2, 3 e 4
|
Vai tranquillo, dovrebbe bastare. Ti faccio uno "schema modello" a cui
dovrai adattare il resto, così non dovresti più avere blocchi.
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 4:13 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 17:48:48 +0200, OcchioDiDrago ha scritto:
| Quote: | Il Tue, 25 Apr 2006 17:20:47 +0200, Will ha scritto:
Praticamente ci sono 2 bottoni e 3 label. I bottoni sono Start e Stop.
Quando premo su Start dovrebbe iniziare a cambiare la il text delle
label seguendo un ritmo (che è scandito da sleep(100)). Quando premo su
Stop poi il tutto dobrebbe fermarsi.
Intanto vedo di recuperare informazioni sui punti 1, 2, 3 e 4 :)
Vai tranquillo, dovrebbe bastare. Ti faccio uno "schema modello" a cui
dovrai adattare il resto, così non dovresti più avere blocchi.
|
....
public void actionPerformed(ActionEvent e) {
if (e.getSource()==Start) {
if (!bstart) bstart=false; else bstart=true;
if (bstart) {
Thread numeraThread=new Thread(new Runnable () {
public void run() {numeraCiclo();}
});
}
}
if (e.getSource()==Stop) {
bstart=false;
}
}
private void numeraCiclo() {
while (bstart) {
//Questo "sleep" non blocca il thread di gestione degli
//eventi
try {Thread.sleep(100);} catch (InterruptedException ex) {}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Qui puoi interagire con il thread di gestione degli
//eventi, invokeLater è stato creato apposta per questo
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
});
iter++;
if (iter>100) {iter=0;break;}
}
}
....
Ho approfittato del fatto che usi una variabile booleana a livello di classe
(bstart) per indicare se il ciclo deve girare o meno. Complimenti (sinceri),
hai pensato all'elaborazione parallela prima ancora di pensare ai Thread!!!
Questo infatti è il metodo più comune (diciamo anche l'unico) per
interrompere l'elaborazione di un Thread senza usare Thread.stop() (che è
deprecato).
Una piccola nota: visto l'uso che fai di bstart, ti conviene dichiararla
come
private volatile boolean bstart;
Questo impedisce al compilatore di ottimizzarla, evitando il rischio di
ottenere valori sfalsati (se ottimizzata, potrebbe capitare che un suo
assegnamento non venga eseguito)
In bocca al lupo!!!
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
Will Guest
|
Posted: Tue Apr 25, 2006 5:12 pm Post subject: Re: Sleep in Java? |
|
|
OcchioDiDrago wrote:
| Quote: | private void numeraCiclo() {
while (bstart) {
//Questo "sleep" non blocca il thread di gestione degli
//eventi
try {Thread.sleep(100);} catch (InterruptedException ex) {}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Qui puoi interagire con il thread di gestione degli
//eventi, invokeLater è stato creato apposta per questo
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
});
iter++;
if (iter>100) {iter=0;break;}
}
}
...
|
Beh che dire: grazie molte davvero!
Quando dici che in quel punto posso interagire con il thread degli
eventi ti riferisci al thread "numeraThread"? Nel caso cosa dovrei fare?
Cioè non ho nessuna esperienza di Thread, mi trovo un attimo spiazzato.
| Quote: | Ho approfittato del fatto che usi una variabile booleana a livello di classe
(bstart) per indicare se il ciclo deve girare o meno. Complimenti (sinceri),
hai pensato all'elaborazione parallela prima ancora di pensare ai Thread!!!
Questo infatti è il metodo più comune (diciamo anche l'unico) per
interrompere l'elaborazione di un Thread senza usare Thread.stop() (che è
deprecato).
|
Ma figurati, sarà stato un caso :)
| Quote: | Una piccola nota: visto l'uso che fai di bstart, ti conviene dichiararla
come
private volatile boolean bstart;
|
Ok fatto!
| Quote: | In bocca al lupo!!!
|
Crepi! |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 8:12 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 18:27:21 +0200, Will ha scritto:
| Quote: | Quando dici che in quel punto posso interagire con il thread degli
eventi ti riferisci al thread "numeraThread"? Nel caso cosa dovrei fare?
Cioè non ho nessuna esperienza di Thread, mi trovo un attimo spiazzato.
|
Vedila così, se può essere più semplice:
Nel momento in cui una delle tue procedure *viene chiamata* (call-back) da
Swing, è il sistema grafico che ti sta dicendo ad esempio "l'utente ha
cliccato su questo pulsante, che faccio?" (il famoso actionPerformed() ). In
quel preciso momento ti trovi nel "contesto" del sistema grafico... la tua
procedura viene letteralmente incorporata nel "protocollo" a cui Swing si
attiene per fare quello che deve (disegnare il contenuto della finestra E
fare attenzione alle azioni dell'utente).
E, in attesa che tu finisca, rimane in sospeso.
Proprio per questo tutti i manuali (anche il tutorial sul sito della Sun)
consigliano di concludere la risposta agli eventi nel modo più *RAPIDO*
possibile. Se nel tuo actionPerformed (o in una qualsiasi procedura che
richiami da li dentro) c'è uno sleep() o in generale se l'elaborazione si
protrae per più di qualche millisecondo, ecco che l'interfaccia grafica
sembra "piantarsi"... è solo Swing che sta aspettando che tu gli restituisca
il controllo.
Un Thread non è altro che un "processore simulato" (per dirla alla buona)
per permetterti di far eseguire più parti del tuo programma
*contemporaneamene*. Se guardi bene l'esempio inserito nel tuo codice:
Thread numeraThread=new Thread(new Runnable () {
public void run() {numeraCiclo();}
});
numeraThread.start();
Prima viene creato il thread (assegnato a numeraThread). Quel costruttore un
po' particolare permette di dire sinteticamente al Thread: "quando parti,
vai ad eseguire la procedura numeraCiclo()". Subito dopo viene richiamato
start(). Questa chiama termina immediatamente, permettendoti di lasciare il
controllo a Swing. Dietro le quinte però la Java Virtual Machine crea un
percorso separato per l'esecuzione parallela du numeraCiclo(), che viene
lanciato *mentre* Swing continua ad interagire allegramente con l'utente.
A questo punto però il thread appena creato non può toccare nulla
dell'ambiente grafico: se il tuo thread cerca di modificare una label nello
stesso momento in cui Swing tenta di ridisegnarla, possono capitare errori
difficilissimi da scovare e risolvere (le cosiddere race conditions). Per
ovviare a questo inconveniente arriva in aiuto invokeLater():
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Qui puoi interagire con il thread di gestione degli
//eventi, invokeLater è stato creato apposta per questo
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
});
In questo modo stai dicendo a Swing: "appena puoi esegui queste modifiche
sull'interfaccia grafica". Swing prende nota, e appena prima di eseguire il
prossimo ridisegno, esegui il tuo codice modificando il contenuto delle
label senza problemi.
Capito tutto?
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
OcchioDiDrago Guest
|
Posted: Tue Apr 25, 2006 8:12 pm Post subject: Re: Sleep in Java? |
|
|
Il Tue, 25 Apr 2006 18:27:21 +0200, Will ha scritto:
| Quote: | Quando dici che in quel punto posso interagire con il thread degli
eventi ti riferisci al thread "numeraThread"? Nel caso cosa dovrei fare?
Cioè non ho nessuna esperienza di Thread, mi trovo un attimo spiazzato.
|
Vedila così, se può essere più semplice:
Nel momento in cui una delle tue procedure *viene chiamata* (call-back) da
Swing, è il sistema grafico che ti sta dicendo ad esempio "l'utente ha
cliccato su questo pulsante, che faccio?" (il famoso actionPerformed() ). In
quel preciso momento ti trovi nel "contesto" del sistema grafico... la tua
procedura viene letteralmente incorporata nel "protocollo" a cui Swing si
attiene per fare quello che deve (disegnare il contenuto della finestra E
fare attenzione alle azioni dell'utente).
E, in attesa che tu finisca, rimane in sospeso.
Proprio per questo tutti i manuali (anche il tutorial sul sito della Sun)
consigliano di concludere la risposta agli eventi nel modo più *RAPIDO*
possibile. Se nel tuo actionPerformed (o in una qualsiasi procedura che
richiami da li dentro) c'è uno sleep() o in generale se l'elaborazione si
protrae per più di qualche millisecondo, ecco che l'interfaccia grafica
sembra "piantarsi"... è solo Swing che sta aspettando che tu gli restituisca
il controllo.
Un Thread non è altro che un "processore simulato" (per dirla alla buona)
per permetterti di far eseguire più parti del tuo programma
*contemporaneamene*. Se guardi bene l'esempio inserito nel tuo codice:
Thread numeraThread=new Thread(new Runnable () {
public void run() {numeraCiclo();}
});
numeraThread.start();
Prima viene creato il thread (assegnato a numeraThread). Quel costruttore un
po' particolare permette di dire sinteticamente al Thread: "quando parti,
vai ad eseguire la procedura numeraCiclo()". Subito dopo viene richiamato
start(). Questa chiamata termina immediatamente, permettendoti di lasciare
il controllo a Swing. Dietro le quinte però la Java Virtual Machine crea un
percorso separato per l'esecuzione parallela di numeraCiclo(), che viene
lanciato *mentre* Swing continua ad interagire allegramente con l'utente.
A questo punto però il thread appena creato non può toccare nulla
dell'ambiente grafico: se il tuo thread cerca di modificare una label nello
stesso momento in cui Swing tenta di ridisegnarla, possono capitare errori
difficilissimi da scovare e risolvere (le cosiddere race conditions). Per
ovviare a questo inconveniente arriva in aiuto invokeLater():
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Qui puoi interagire con il thread di gestione degli
//eventi, invokeLater è stato creato apposta per questo
lchan.setText(Integer.toString(midi.myn[track].myp[iter].chan));
lpitch.setText(Integer.toString(midi.myn[track].myp[iter].nota));
lvel.setText(Integer.toString(midi.myn[track].myp[iter].velocity));
}
});
In questo modo stai dicendo a Swing: "appena puoi esegui queste modifiche
sull'interfaccia grafica". Swing prende nota, e appena prima di eseguire il
prossimo ridisegno, esegue il tuo codice modificando il contenuto delle
label senza problemi.
Capito tutto?
--
Fermiamo scientology prima che sia troppo tardi!!!
http://xenu.com-it.net - http://xenu.freewinds.cx/ - http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo) |
|
| Back to top |
|
 |
Will Guest
|
Posted: Tue Apr 25, 2006 9:13 pm Post subject: Re: Sleep in Java? |
|
|
OcchioDiDrago wrote:
Si abbastanza!
Che dire sono senza parole! La tua gentilezza e disponibilità è unica.
Ti ringrazio ancora moltissimo! |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|