Vai al contenuto

Primario: Sky Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Secondario: Sky Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Sfondo: Blank Waves Squares Notes Sharp Wood Rockface Leather Honey Vertical Triangles
Corsi di Laurea










ROX @ Unisa - Forum degli studenti di Ingegneria utilizza i cookie. Se prosegui la navigazione accetti il loro uso.    Accetto l'uso dei cookie
-->
Foto

Swing & threads


  • Effettua l'accesso per rispondere
Questa discussione ha avuto 12 risposta/e

#1
DeAndreon

DeAndreon

    Advanced Member

  • Utente
  • StellaStellaStella
  • 562 Messaggi:
Ciao a tutti! mi sto un pò divertendo con threads e swing in vista dell'orale del primo marzo.
Sto provando a vedere la reattività della GUI quando un compito pesante finisce nel event dispatcher (thread che si occupa di eseguire i compiti dei listener e cambiamenti sull'interfaccia) oppure in un thread apparte.
Il risultato è sorprendente però non riesco a capire una cosa.
Ecco il codice da me creato(sono le due classi interne che implementano i listener per i miei 2 bottoni dell'applicazione):

public class button1Listener implements ActionListener{

public void calcolone(){
Runnable r = new Runnable(){
public void run(){

int i=0;
while(true){
i++;
i--;
}

}
};
Thread t = new Thread(r);
t.start();

}
public void actionPerformed(ActionEvent e){

calcolone();


}


}


public class button2Listener implements ActionListener{

public void actionPerformed(ActionEvent e){

int i=0;
while(true){
i++;
i--;
}


}
}



nel primo listener ho creato un metodo calcolone con un ciclo infinito. Ho istanziato un oggetto di tipo runnable implementando l'interfaccia runnable e il suo metodo run che contiene il ciclo. Dopo ho creato un thread a cui passo l'oggetto runnable che contiene run implementato. Actionperformed richiama il metodo calcolone.
Il secondo invece è un semplice listener dove actionperformed esegue il ciclo.
Ora, provando il programma, con il primo pulsante l'interfaccia rimane attiva cioè non si blocca mentre se premo il secondo pulsante si blocca.
Ora vorrei capire...

Ma io nel primo listener nell'actionperformed chiamo calcolone() che a sua volta crea un thread? E dato che actionperformed va nell'event dispatcher non ci va anche il thread che creo in calcolone()?
Perchè non si ha lo stesso effetto del secondo listener?
cioè vorrei capire perchè il thread di calcolone() non va nell'evet dispatcher dato che actionperformed richiama calcolone()...

Grazie a tutti!


"Sir Daniel Fortesque! In ritorno dalla terra dei morti!"(Winston, l'Assistente Fantasma, al risveglio di Sir Daniel Fortesque).

#2
DeAndreon

DeAndreon

    Advanced Member

  • Utente
  • StellaStellaStella
  • 562 Messaggi:
Mi do una risposta da solo:

allora, dato che è un thread, questo pezzo di codice "uscirà" dal event dispatcher per essere eseguito in parallelo o in concorrenza con l'event dispatcher tipo quando abbiamo il thread del main() e all'interno del main() lanciamo un thread che verrà eseguito apparte e in parallelo con il thread del main().
Giusto?

Grazie :)
"Sir Daniel Fortesque! In ritorno dalla terra dei morti!"(Winston, l'Assistente Fantasma, al risveglio di Sir Daniel Fortesque).

#3
dome88

dome88

    Advanced Member

  • Utente
  • StellaStellaStella
  • 113 Messaggi:
ciao..io penso di si perchè cmq crei un thread a parte...poi il compito passerà allo scheduler del sistema operativo che si incaricherà di richiamare il metodo run all'interno di calcolone()....Credo! :D ......aspettando che qualcuno ci illumini....
Ma con il primo listener l'interfaccia non rimane bloccata?Mentre nel secondo viene bloccata hai detto?

ps anche io devo fare l'orale il primo marzo...a parte questo che esercizi stai facendo? Io sto da un pò sull'ereditarietà e sul polimorfismo....

#4
Enrico

Enrico

    Advanced Member

  • Utente
  • StellaStellaStella
  • 305 Messaggi:
Ho un problema che forse ha a che fare con i thread...

Ho creato una interfaccia grafica con un bottone_1.
Quando clicco su questo bottone_1 si apre una seconda finestra con un bottone_2.
Questa seconda finestra ha dei campi per inserire una entry in una Map non appena viene cliccato il bottone_2.

Il problema che mi si presenta è che se apro e chiudo questa seconda finestra 10 volte e cerco di inserire una nuove entry alla decima apertura, il programma tenta 10 volte l'inserimento!

Datemi una mano vi scongiuro! E' come se una volta chiusa una finestra rimanesse aperto un thread che risponde ai comandi di della stessa interfaccia in un secondo momento, come se non fosse mai stata chiusa...
"All men are equal, but some are more equal than others."
George Orwell, Animal farm

#5
DomenicoAngri

DomenicoAngri

    Advanced Member

  • Utente
  • StellaStellaStella
  • 198 Messaggi:
Allora ragazzi andiamo con ordine.
Rispondo prima alla domanda di Andrea sperando di essere chiaro ed esauriente:

Da quello che ho capito, Andrè tu hai creato una GUI con due tasti. Il primo button, ti esegue attraverso un thread un ciclo infinito, mentre il secondo fa lo stesso, però senza il thread.
Allora, una risposta potrebbe essere la seguente:

- Quando tu istanzi un thread e poi lo "avvii" attraverso il metodo .start(); il thread non si avvia immediatamente, ma bensì dice allo scheduler del SO che è pronto per essere eseguito. E' il SO che decide poi se lo vuole avviare subito o meno. In tal caso potrebbe darsi che premendo il button1, il SO mette come in attesa il thread per poi avviarlo in seguito, mentre il secondo button, non essendo un thread, viene avviato dal SO operativo immediatamente e non so forse, si blocca perchè è un ciclo infinito...
Potresti provare ad esempio a premere il button1 ed aspettare per vedere se prima o poi la GUI si blocca. Domani cmq provo a farlo anche io e ti faccio sapere!

- Come regola appena clicchi il button1 il thread ti viene immediatamente istanziato.

Ho notato però una cosa.
Tu fai:

public void calcolone(){
Runnable r = new Runnable(){
public void run(){

int i=0;
while(true){
i++;
i--;
}

}
};


Cioè è lecito fare ciò? Come regola dovresti creare una classe che implementi runnable od estendi thread, e poi da li fare il metodo run nel quale ci metti il tuo ciclo infinito, dopodichè nel listener del button1 ti istanzi il tuo thread e fai .start() per avviarlo. E' forse questo il problema? Domani cmq provo e ti faccio sapere.

@Per Enrico:

Scusa ma non ho ben capito il tuo problema :P , cosa accade precisamente?? E cosa vuoi invece che faccia?
In ogni modo, se tu non hai usato i thread, il problema non è relativo ad essi, ma ad un errore nel codice del tuo programma! ;) Esponimi cmq bene il problema che cerco di esserti d'aiuto! ;)

#6
Blackjack

Blackjack

    Moderatore globale

  • Moderatore
  • 2542 Messaggi:

Ho un problema che forse ha a che fare con i thread...

Ho creato una interfaccia grafica con un bottone_1.
Quando clicco su questo bottone_1 si apre una seconda finestra con un bottone_2.
Questa seconda finestra ha dei campi per inserire una entry in una Map non appena viene cliccato il bottone_2.

Il problema che mi si presenta è che se apro e chiudo questa seconda finestra 10 volte e cerco di inserire una nuove entry alla decima apertura, il programma tenta 10 volte l'inserimento!

Datemi una mano vi scongiuro! E' come se una volta chiusa una finestra rimanesse aperto un thread che risponde ai comandi di della stessa interfaccia in un secondo momento, come se non fosse mai stata chiusa...


bisognerebbe vedere il codice, perchè molto probabilmente hai fatto qualche errore da qualche parte!
Immagine inviata
Immagine inviata
Immagine inviata

"L'amore è la capacità di avvertire il simile nel dissimile"

#7
DeAndreon

DeAndreon

    Advanced Member

  • Utente
  • StellaStellaStella
  • 562 Messaggi:

Allora ragazzi andiamo con ordine.
Rispondo prima alla domanda di Andrea sperando di essere chiaro ed esauriente:

Da quello che ho capito, Andrè tu hai creato una GUI con due tasti. Il primo button, ti esegue attraverso un thread un ciclo infinito, mentre il secondo fa lo stesso, però senza il thread.
Allora, una risposta potrebbe essere la seguente:

- Quando tu istanzi un thread e poi lo "avvii" attraverso il metodo .start(); il thread non si avvia immediatamente, ma bensì dice allo scheduler del SO che è pronto per essere eseguito. E' il SO che decide poi se lo vuole avviare subito o meno. In tal caso potrebbe darsi che premendo il button1, il SO mette come in attesa il thread per poi avviarlo in seguito, mentre il secondo button, non essendo un thread, viene avviato dal SO operativo immediatamente e non so forse, si blocca perchè è un ciclo infinito...
Potresti provare ad esempio a premere il button1 ed aspettare per vedere se prima o poi la GUI si blocca. Domani cmq provo a farlo anche io e ti faccio sapere!

- Come regola appena clicchi il button1 il thread ti viene immediatamente istanziato.

Ho notato però una cosa.
Tu fai:


public void calcolone(){
Runnable r = new Runnable(){
public void run(){

int i=0;
while(true){
i++;
i--;
}

}
};


Cioè è lecito fare ciò? Come regola dovresti creare una classe che implementi runnable od estendi thread, e poi da li fare il metodo run nel quale ci metti il tuo ciclo infinito, dopodichè nel listener del button1 ti istanzi il tuo thread e fai .start() per avviarlo. E' forse questo il problema? Domani cmq provo e ti faccio sapere.


Ciao! Se guardi bene nella funzione compitone ho fatto come hai detto tu ;) Ho implementato l'interfaccia runnable e poi istanziato un oggetto runnable per poi passarlo a thread ed infine avviarlo con start ;)
Quello che sono riuscito a capire è che mentre il secondo bottone svolge il ciclo infinito all'interno del event dispatcher perchè il codice è presente nell'actionperformed, nel primo bottone il ciclo infinito viene svolto in un thread apparte così da evitare di intasare l'event dispatcher ed avere l'interfaccia sempre fluida e mai bloccata.
Nel lanciati una decina di thread con il primo bottone, interfacca sempre lucida mentre il computer è andato in tilt XD XD XD Ho un dual core, quando istanzio un thread, la cpu è al 50% di utilizzo mentre se ne metto 2 è al 100%. Comunque penso di aver capito. Quando istanzio il nuovo thread non va nell'event dispatcher ma viene eseguito apparte.
Così dovrebbe essere :)
"Sir Daniel Fortesque! In ritorno dalla terra dei morti!"(Winston, l'Assistente Fantasma, al risveglio di Sir Daniel Fortesque).

#8
DomenicoAngri

DomenicoAngri

    Advanced Member

  • Utente
  • StellaStellaStella
  • 198 Messaggi:
Noo vabbè io dicevo di farlo completamente in una classe differente!! Cmq apparte questo, scusa anche se il ciclo è fatto in un thread separato, non dovrebbe cmq intasarti il computer? A maggior ragione se poi ne fai 4, 5 e così via?? Non capisco... Vabbè cmq se non ho il codice davanti non riesco a focalizzare bene il problema, ora lo faccio e magari ne discutiamo! ;)

#9
Enrico

Enrico

    Advanced Member

  • Utente
  • StellaStellaStella
  • 305 Messaggi:
Ah ho trovato il baco, era stata una idiozia...

In pratica (non mi picchiate) avevo richiamato il metodo che aggiungeva i listener non nel costruttore ma nel metodo ActionPerformed. In pratica ogni volta che cliccavo il pulsante "Aggiungi" e usciva la seconda interfaccina grafica aggiungevo gli stessi listener agli stessi bottoni ogni volta che aprivo la seconda interfaccia.

Di conseguenza questa seconda interfaccia eseguiva il comando tante volte quanti listener aveva ( tante volte quanto aprivo la finestra...)
"All men are equal, but some are more equal than others."
George Orwell, Animal farm

#10
DeAndreon

DeAndreon

    Advanced Member

  • Utente
  • StellaStellaStella
  • 562 Messaggi:

Noo vabbè io dicevo di farlo completamente in una classe differente!! Cmq apparte questo, scusa anche se il ciclo è fatto in un thread separato, non dovrebbe cmq intasarti il computer? A maggior ragione se poi ne fai 4, 5 e così via?? Non capisco... Vabbè cmq se non ho il codice davanti non riesco a focalizzare bene il problema, ora lo faccio e magari ne discutiamo! ;)


Infatti è così. Se faccio più di un thread, va in pallone il pc XD Ho un dual core sul portatile. In pratica, se creo un thread se la vede con il primo core ed infatti nel task manager la cpu è al 50%, se ne creo un'altro il pc va in pallone perchè anche il secondo core entra in azione XD
Ci troviamo.

Comunque, se vi va, scaricatevi questo programmino che ho fatto. E' un banale player di mp3. Ma spero che capirete che non è uno scherzo farlo XD
http://www.megaupload.com/?d=C88CHXZC

Vedete se vi piace ;)
"Sir Daniel Fortesque! In ritorno dalla terra dei morti!"(Winston, l'Assistente Fantasma, al risveglio di Sir Daniel Fortesque).

#11
dome88

dome88

    Advanced Member

  • Utente
  • StellaStellaStella
  • 113 Messaggi:

Comunque, se vi va, scaricatevi questo programmino che ho fatto. E' un banale player di mp3. Ma spero che capirete che non è uno scherzo farlo XD
http://www.megaupload.com/?d=C88CHXZC

Vedete se vi piace ;)


volevo vederlo però non va....dice che è temporaneamente non disponibile....ma mica è tutto il codice??Sono curioso di sapere come si potrebbe fare :D

#12
DomenicoAngri

DomenicoAngri

    Advanced Member

  • Utente
  • StellaStellaStella
  • 198 Messaggi:
waaaaaaaaaa bellissimo!!!! ahhahahahahah che sfizioo!!!! Complimenti!!! Anche tu ti stai dilettando nel creare programmini del genere eh?!?! ahahahahhah bellissimo!!!

#13
dome88

dome88

    Advanced Member

  • Utente
  • StellaStellaStella
  • 113 Messaggi:
bravo veramente!Non è open source? :asd:




Leggono questa discussione 0 utenti

0 utenti, 0 ospiti, 0 utenti anonimi