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

    Aspettare che un thread termini

    Ciao ragazzi, ho un problema riguardante la gestione dei thread.

    Ad un certo punto della mia classe, il cui thread (chiamiamolo A) non posso crearlo io (viene creato dal Application Server), devo creare un altro thread (chiamiamolo B) e fare in modo che questo venga eseguito solo DOPO che il thread A è concluso.


    Per chi conosce Swing dovrei fare qualcosa di simile a:

    Codice PHP:
    SwingUtilities.invokeLater(threadDipendente
    Ma non funziona su processi non-AWT. Quindi come potrei fare?

    Grazie molte.

  2. #2
    Dovresti passare al Thread da avviare in ritardo un puntatore al Thread padre, avviare subito il thread figlio ed aspettare nel thread figlio che il thread padre joini (aspetta la conclusione del thread padre) e poi le operazioni dopo il join del thread verranno eseguite dopo la conclusione del thread padre.

    Ho fatto quest'esempio
    codice:
            class RunnableChild implements Runnable {
    
                public Thread parent;
    
                @Override
                public void run() {
                    try {
                        System.out.println("Aspetto il join del thread principale ...");
                        parent.join();
                        System.out.println("Thread principale joinato!");
                        Thread.currentThread().sleep(5000);
                        System.out.println("Fine thread figlio!");
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
    
                public RunnableChild(Thread parent) {
                    this.parent = parent;
                }
            }
            Thread child = new Thread(new RunnableChild(Thread.currentThread()));
            child.start();
            System.out.println("main() End!");
        }
    Credo sia questo quello che intendevi
    lolide
    Java Programmer

    Informati

  3. #3
    Grazie della risposta, ci ho provato, ma mi sono accorto che il Thread padre non muore mai!! (è gestito dall'Applicatoin Server).

    Alla fine ho risolto (mi sono accontentato diciamo) di utilizzare il "pattern" del produttore-consumatore.
    Per cui, fino a quando il thread principale non pone un flag a true in un oggetto condiviso col thread figlio (oggetto con metodi synchronized), il figlio non può proseguire.

  4. #4
    Originariamente inviato da scrittore80
    Grazie della risposta, ci ho provato, ma mi sono accorto che il Thread padre non muore mai!! (è gestito dall'Applicatoin Server).

    Alla fine ho risolto (mi sono accontentato diciamo) di utilizzare il "pattern" del produttore-consumatore.
    Per cui, fino a quando il thread principale non pone un flag a true in un oggetto condiviso col thread figlio (oggetto con metodi synchronized), il figlio non può proseguire.
    Ma è una Servlet?

    Tu vorresti eseguire un Thread diciamo dopo una certa operazione... perchè non lo starti dopo quell'operazione invece di usare un flag?
    Tanto il Thread padre non rimane bloccato ma continua l'esecuzione...
    lolide
    Java Programmer

    Informati

  5. #5
    Concettualmente sì, è una specie di Servlet.

    Tu vorresti eseguire un Thread diciamo dopo una certa operazione... perchè non lo starti dopo quell'operazione invece di usare un flag?
    Perchè il "dopo una certa l'operazione" è il return del metodo del thread principale.

    Il figlio dev'essere eseguito solo dopo il return del padre.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non mi tornano i conti: se un metodo fa un return, significa che ritorna, quindi se fai una cosa dopo il return del padre, il padre ha terminato, dipende da come hai avviato i thread e se il thread padre è il principale, tutti i figli terminano.

    Non mi torna anche usare thread, ma sincronizzarli alla terminazione di uno...boh, forse non avendo il quadro di insieme non so bene cosa pensare, ma in quello che hai fatto c'è qualcosa che non mi torna.
    Produttore/consumatore richiede che entrambi sono in esecuzione contemporaneamente, altrimenti è una sequenza e i thread ti portano solo un overhead non necessario
    RTFM Read That F*** Manual!!!

  7. #7
    Originariamente inviato da scrittore80
    Concettualmente sì, è una specie di Servlet.


    Perchè il "dopo una certa l'operazione" è il return del metodo del thread principale.

    Il figlio dev'essere eseguito solo dopo il return del padre.
    Perchè dev'essere eseguito dopo il return?

    Cioè avviando un nuovo Thread da un thread padre non fa bloccare il Thread padre..
    Quindi concettualmente se avvii il thread figlio anche prima del return, il return poi lo fa anche con il thread figlio in esecuzione...
    se tu vuoi invece che il Thread padre finisca proprio ed usando un join vedi che non finisce mai, evidentemente quel Thread viene tenuto sempre aperto.
    Dipende da che applicazione è, magari se ci fai vedere o ci spieghi come funziona potremmo anche capire come fare.

    Se è una Servlet hai ragione tu cmq, il Thread della servlet non viene mai fermato quindi è impossibile avviare il figlio dopo la chiusura del padre.
    lolide
    Java Programmer

    Informati

  8. #8
    Lo scenario dovrebbe essere questo:
    Una servlet (su cui non ho accesso) crea un oggetto della mia classe e gli invoca un metodo. Io dovrei far partire un altro thread DOPO che questo metodo invocato dalla servlet è terminato.

    Vi posto il codice semplicificato delle 2 classi.

    Metodo invocato dalla servlet, al termine del quale dev'essere eseguito il thread figlio.
    codice:
    public void esegui() throws Exception
        {
            try{
                ThreadController controller = new ThreadController();
                Thread thisThread = Thread.currentThread();
                SubThread subThread = new SubThread(controller);
                subThread.start();
                thisThread.sleep(7000);
                System.out.println("Ho finito, avviso il controllore");
                controller.setFinitoThenNotify();
                
            }
            catch(Exception ex)
            {
                System.out.println("Eccezione!");
                ex.printStackTrace();
            }
        }

    ThreadFiglio
    codice:
     
    public class SubThread extends Thread{
    
        ThreadController controller;
        public SubThread(ThreadController controller)
        {
           
            this.controller=controller;
        }
    
    
        public void run()
        {
            try{
                System.out.println("SubThread: Chiedo se ha finito");
                controller.aspettaSeNonFinito();
                System.out.println("SubThread: Mi sono svegliato, vuol dire che ha finito, aspetto ancora qualche secondo...");
                            
                //per sicurezza, dopo che ho ricevuto OK, aspetto ancora 3 secondi, poi proseguo
                sleep(4000);
                System.out.println("SubThread: Ora parto!");
     
                //elaborazione del thread Figlio
            }
            catch(Exception e)
            {
                System.out.println("SubThread: Eccezione!");
            }
    
        }
    
    }
    Questa è la classe dell'oggetto condiviso, che dice se il figlio può partire.
    codice:
     
    public class ThreadController {
    
        private boolean finito=false;
    
        public synchronized void aspettaSeNonFinito() {
            try{
               if(!finito)
                {
                    System.out.println("ThreadController: Faccio aspettare perche il thread principale non ha finito");
                    wait();
                    System.out.println("ThreadController: Sono stato svegliato, il thread principale ha finito");
                }
            }
            catch(Exception e)
            {
                System.out.println("ThreadController: Eccezione!");
            }
            
        }
    
         public synchronized void setFinitoThenNotify() {
            finito = true;
            System.out.println("ThreadController: Mi è arrivato il permesso di svegliare il thread dormiente, ora lo faccio");
            notifyAll();
        }
    
    }
    Ho risolto così, mi pare una buona soluzione. Oltretutto il figlio aspetta qualche secondo prima di partire davvero, per lasciare alla servlet il tempo di elaborare la risposta del mio metodo e fare qualcos'altro.
    Il mio problema lo considero risolto, grazie per l'interessamento.

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    bah le temporizzazioni così lasciano il tempo che trovano.
    Una domanda: se tu sei su una servlet, come comunichi con la stessa?
    Ho sempre l'impressione che stai facendo confusione nella modellizzazione della soluzione, dovresti spiegare bene il problema e il contesto, ho capito che sei su una servlet, ma servlet suppone un servlet container e spesso computer differenti, quindi non ho capito bene a che ti servono i thread visto che tendenzialmente si esegue in contesti differenti.
    RTFM Read That F*** Manual!!!

  10. #10
    io non comunico con la servlet, è lei che mi crea, invoca e legge la mia risposta. Io non ho "giurisdizione" su di essa. E siamo tutti sullo stesso pc.

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.