Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: Interrompere un thread

  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    22

    Interrompere un thread

    Ciao a tutti,
    ho un piccolo problema.
    Nel mio programma sto gestendo un thread ma non riesco a interromperne l'esecuzione.

    Posto di seguito il codice:

    nel main faccio partire il thread


    codice:
    istanza.getVeicoli().get(0).start();

    codice:
    public void run()
    {
    while(!stopThread)
    {    
       try {
        esecuzione();
        } catch (CloneNotSupportedException e) {
    // TODO Auto-generated catch block
            e.printStackTrace();
            this.stopRunning();
            }
        }
    }

    e il metodo stopRunning è il seguente


    codice:
    public void stopRunning()
    {
    stopThread = true;
    }



    Nel metodo esecuzione() è racchiuso il comportamento del thread tra cui la chiamata a un metodo synchronized che non è della classe del thread ma di un'altra classe. Mi spiego meglio: il thread è della classe Veicolo, mentre il metodo synchronized è della classe Istanza. La classe Istanza contiene tra i suoi attributi un certo numero di Veicolo.

    Una cosa che capisco poco è inoltre questa: fatta partire l'esecuzione del main, in realtà prima mi stampa le azioni che sono scritte successivamente all'avvio del thread. Come mai questo avviene?
    Ultima modifica di LeleFT; 25-06-2014 a 12:34 Motivo: Tolta la formattazione dal codice

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da kiaBs Visualizza il messaggio
    e il metodo stopRunning è il seguente

    codice:
    public void stopRunning()
    {
    stopThread = true;
    }
    Questo di per sé può andare bene. Ma c'è un aspetto importante della variabile di istanza stopThread. Dato che non c'è alcuna sincronizzazione riguardo l'accesso a stopThread, questa variabile deve essere perlomeno marcata con la parola chiave volatile.
    Se è volatile, è garantito che la modifica di stopThread da parte di un thread X sia assolutamente "visibile" dal thread che esegue il tuo run(). Altrimenti non ci sono garanzie.

    Quote Originariamente inviata da kiaBs Visualizza il messaggio
    Una cosa che capisco poco è inoltre questa: fatta partire l'esecuzione del main, in realtà prima mi stampa le azioni che sono scritte successivamente all'avvio del thread. Come mai questo avviene?
    Se fai:

    codice:
    unThread.start();
    System.out.println("test");

    Lo start() di per sé non avvia ancora un bel niente. Fa solo passare il thread dallo stato "new" (oggetto Thread appena creato) allo stato "runnable" (cioè può essere eseguito). È poi lo scheduler dei thread che decide quando far partire effettivamente il run().
    Quindi è perfettamente possibile che quella scritta "test" (e anche qualcos'altro dopo eventualmente) venga eseguita prima che il run() inizi la esecuzione!

    Quando si ha a che fare con i thread bisogna tenere a mente che ci sono ben poche cose davvero "garantite" e prevedibili.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    22
    Ok, proverò subito. Grazie mille!

    Quindi se volessi fare delle ulteriori operazioni, come banali calcoli o far partire una nuova azione per i thread, dopo l'esecuzione del metodo esecuzione() di ognuno dei thread, devo prima accertarmi che siano tutti morti e poi far partire il resto?

    Grazie ancora per la risposta pronta e chiara!

  4. #4
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Beh, se quelle operazioni dipendono dall'esito dei thread precedenti sì, devi aspettare che finiscano (puoi usare il metodo join()).
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    22
    Ho fatto partire due thread con le modifiche suggerite.
    Ora noto che l'esecuzione si interrompe a volte dopo 7 iterazioni, altre volte dopo 13 ritornandomi questo errore:

    Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2734)
    at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
    at java.util.ArrayList.add(ArrayList.java:351)
    at main.Istanza.getShortestPathTo(Istanza.java:653)
    at main.Istanza.calcoloCamminoMin(Istanza.java:431)
    at main.Veicolo.esecuzioneGreedy(Veicolo.java:130)
    at main.Veicolo.run(Veicolo.java:116)
    Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2734)
    at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
    at java.util.ArrayList.add(ArrayList.java:351)
    at main.Istanza.getShortestPathTo(Istanza.java:653)
    at main.Istanza.calcoloCamminiMinRic(Istanza.java:484)
    at main.Istanza.raggiungoRicarica(Istanza.java:662)
    at main.Veicolo.esecuzioneGreedy(Veicolo.java:174)
    at main.Veicolo.run(Veicolo.java:116)

    Mi sapreste dire come mai questo comportamento avviene ad un numero diverso di iterazioni?
    Vi ringrazio moltissimo!

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da kiaBs Visualizza il messaggio
    Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space
    A fronte di un OutOfMemoryError, si possono pensare due cose:
    a) il tuo codice ha davvero bisogno di molta memoria, per motivi ben precisi e che ovviamente devi ben conoscere e prevedere tu. In tal caso è sufficiente avviare la JVM sempre specificando un appropriato heap-space iniziale/massimo.
    b) il tuo codice è scritto male e/o fa un "cattivo" uso degli oggetti. Motivo per cui, anche con heap-space "ragionevoli", fallisce abbastanza velocemente. In tal caso non ti aspettavi appunto un tale uso eccessivo.

    Quale è dei due? Che cosa fa il tuo codice?
    Ultima modifica di andbin; 25-06-2014 a 16:54
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    22
    E' molto probabile che sia perché ha bisogno di tanta memoria.
    Sto risolvendo un problema di Arc Routing, e i miei thread devono spostarsi di nodi in nodi calcolando cammini minimi verso varie destinazioni. Facendo una serie di stampe di prove, effettivamente il programma si "incanta" nel calcolare i cammini minimi verso vari nodi. In quella porzione di codice non ci sono riferimenti a oggetti: applico un algoritmo di calcolo di distanze.

    for (Nodo nodo:this.getNodi())
    {
    //System.out.println("qui");
    Cammino c = new Cammino(nodo,nodo.minDistance,this.getShortestPathTo(nodo));
    listaTotale.aggCammino(c);
    }

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da kiaBs Visualizza il messaggio
    E' molto probabile che sia perché ha bisogno di tanta memoria.
    Sto risolvendo un problema di Arc Routing, e i miei thread devono spostarsi di nodi in nodi calcolando cammini minimi verso varie destinazioni. Facendo una serie di stampe di prove, effettivamente il programma si "incanta" nel calcolare i cammini minimi verso vari nodi. In quella porzione di codice non ci sono riferimenti a oggetti: applico un algoritmo di calcolo di distanze.
    Questo codice che hai postato non "dice" più di tanto (almeno a me). Dovresti indagare tu, magari facendo del debugging o anche solo loggando certe informazioni.

    Il problema tecnico è chiaro dallo stack trace:

    codice:
    at java.util.Arrays.copyOf(Arrays.java:2734)
    at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
    at java.util.ArrayList.add(ArrayList.java:351)
    at main.Istanza.getShortestPathTo(Istanza.java:653)

    Il tuo getShortestPathTo aggiunge un elemento ad un ArrayList. L'aggiunta è tale per cui l'ArrayList deve espandere il suo array interno. Ma nella istanziazione operata da copyOf fallisce.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    22
    Potrebbe essere invece che è perché i due thread magari lo stanno facendo contemporaneamente? E quindi, anche se non si tratta di risorse critiche, appesantisce l'esecuzione e quindi la memoria? Però non mi spiego come mai a volte si ferma prima e a volte dopo..

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da kiaBs Visualizza il messaggio
    Potrebbe essere invece che è perché i due thread magari lo stanno facendo contemporaneamente?
    I due thread operano concorrentemente sullo stesso oggetto ArrayList? ArrayList non è thread-safe, quindi senza aver previsto una sincronizzazione "a monte", sarebbe già solo questo inappropriato.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Tag per questa discussione

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.