Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > Java
You last visited: Today at 02:25

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Threads managen / Schleife fortsetzen, wenn Thread beendet

Discussion on Threads managen / Schleife fortsetzen, wenn Thread beendet within the Java forum part of the Coders Den category.

Closed Thread
 
Old   #1
 
Zunft's Avatar
 
elite*gold: 0
Join Date: Mar 2013
Posts: 3,184
Received Thanks: 1,317
Threads managen / Schleife fortsetzen, wenn Thread beendet

Hallo zusammen,

mein Problem ist folgendes:

Ich habe in einer ForEach-Schleife 3 Threads, die alle gleichzeitig ausgeführt werden müssen, allerdings auch jeweils nur diese 3 gleichzeitig. In der Schleife ist es aber so, dass hier dann alle "3er-Pakete" so oft ausgeführt werden, wie die Schleife es angibt.

Also zusammengefasst: Ich möchte die Schleife erst dann fortsetzen, wenn alle Threads beendet sind, aber keine weitere Schleife á la:

Code:
while(!finish)
{

}
hinzufügen, da sich so die GUI aufhängt.

Code:
Task progress = new Task<Void>() {
            @Override
            public Void call() {

                this.updateProgress(dwtable.getItems().size(), 1);
                
                while (ydown.Percent < 100) {
                    if (isCancelled()) {
                        break;
                    }
                    setPercent(null, ydown.Percent);
                    updateProgress(ydown.Percent, 100);
                                        
                    System.out.println("Prozent: " + ydown.Percent);
                    
                }
                updateProgress(100, 100);
                ydown.Percent = 0;

                return null;
            }
        };

        Task download = new Task<Void>() {
            @Override
            public Void call() {

                ydown.download(dwtable.getItems().get(zaehler).getYouTube());
                zaehler++;
                finish = true;
                return null;
            }
        };

        for(Track tr : dwtable.getItems()) 
        {
                        
            try {
                executor.execute((Runnable) tr);
                testProg.progressProperty().bind(progress.progressProperty());

                executor.execute(download);
                executor.execute(progress);
                finish = false;
               
                
            } catch (Exception ex) {
                Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
und in Track:

Code:
    @Override
    protected Void call() throws Exception
    {
        
        mfc = new MainFrameController();
        this.updateProgress(ProgressIndicator.INDETERMINATE_PROGRESS, 100);
        
        while(percent < 100)
        {
            updateProgress(percent, 100);
        }
        
        updateProgress(100, 100);
        percent = 0;
        
        return null;
    }
Zunft is offline  
Old 02/01/2015, 21:56   #2
 
XxharCs's Avatar
 
elite*gold: 34
Join Date: Apr 2011
Posts: 1,475
Received Thanks: 1,227
Verwende ThreadPoolExecutor und sogenannte "Watchdogs".

Glücklicherweise habe ich auf meinen Github Acc ein Programm welches sehr stark mit Threads arbeitet, und da werden ThreadPoolExecutoren und Watchdogs verwendet.

Wirf ein Blick rein, vielleicht wird es dir helfen:
Und das Projekt generell:


Und was ich von deinem Code herleiten konnte, willst du eine Progressbar(und andere Progress änderungen) darstellen oder? Ich würde dann das Observer verwenden(Observer Nutzung auch auf meinem Git Acc: )
XxharCs is offline  
Thanks
1 User
Old 02/01/2015, 22:08   #3
 
Zunft's Avatar
 
elite*gold: 0
Join Date: Mar 2013
Posts: 3,184
Received Thanks: 1,317
Quote:
Originally Posted by XxharCs View Post
Und was ich von deinem Code herleiten konnte, willst du eine Progressbar(und andere Progress änderungen) darstellen oder? Ich würde dann das Observer verwenden(Observer Nutzung auch auf meinem Git Acc: )
Prinzipiell ja, hier geht es aber nicht um eine einzige Progressbar sondern um mehrere ProgressBars, die in einer TableView sind.

Zunft is offline  
Old 02/01/2015, 23:02   #4
 
XxharCs's Avatar
 
elite*gold: 34
Join Date: Apr 2011
Posts: 1,475
Received Thanks: 1,227
Ich werde mich morgen hier nochmal melden/diesen Beitrag editieren mit einer Lösung, weil ich schon eine Idee habe (Natürlich falls sich keiner schon vor mir gemeldet hat )

Edit: Ohne das du jetzt groß dein Design änderst, und sehe ja das dein Code den ExecuterService(nice! ) verwendet, müsstest du trotzdem eine while-Schleife reinhauen :/
Code:
executor.shutdown(); // den ExecuterService schließen nachdem du Threads mit ihm gestartet hast
	
while (!executor.isTerminated()) {} // wartet bis alle Thread fertig sind
Bei dem Observer Prinzip müsstest du in diesem Fall etwas mehr Code ändern :/ Lass mich wissen falls du es doch anders haben möchtest, und ich schreibe ne kurze Application die mit mehreren Progressbars arbeitet und das Obserer Prinzip verwendet

Edit2: Obwohl wenn du das Observer Pattern anwendest, müsstest du auch irgendwann mal nachfragen ob progress jetzt 100% ist oder so, zwar ist man da Flexibler wie zb if(progress == 100) dann enable wieder diese bestimmten Funktionen oder so.
Was genau sollte denn passieren nachdem die Threads fertig sind? Sind dann bestimmte Funktionen wieder zur Verfügung gestellt oder wie?
XxharCs is offline  
Thanks
1 User
Old 02/02/2015, 14:11   #5
 
Zunft's Avatar
 
elite*gold: 0
Join Date: Mar 2013
Posts: 3,184
Received Thanks: 1,317
Ich werde nachher den kompletten relevanten Code einstellen. Der Code ist allerdings !noch! ziemlich unübersichtlich und noch nicht wirklich Objektorientiert.

Also das Prinzip ist folgendermaßen - hoffe es ist halbwegs verständlich dargestellt:

-> Downloadknopf gedrückt
-> Für jeden Track (Musikstück) in TableView
--> Lade Track herunter
--> Update Gesamtprogressbar (Alle Tracks) anhand (noch nicht implementiert, testweise lediglich Fortschritt von einzelnem Track)
--> Update jeweilige Progressbar des Tracks im TableView
--> Wenn Track heruntergeladen, starte Download des nächsten Tracks
--> GUI soll weiterhin aktiv bleiben ohne zu blockieren

*Edit: Das sollte alles relevantes sein. Ich muss mich leider beeilen, daher kann es sein, dass etwas fehlt.

MainFrameController:

Track:

Youtube:
Zunft is offline  
Old 02/02/2015, 15:25   #6
 
XxharCs's Avatar
 
elite*gold: 34
Join Date: Apr 2011
Posts: 1,475
Received Thanks: 1,227
Asooo, ja das kann man auf 2 Arten machen, die eine Art mit join() und die andere ivokeAll() oder submit().

Bei der 1 Art:
Die Threads in ein Array packen, sie starten und dann mit einer Schleife für die Threads ein join(), also:
Code:
for(i = 0; i < threads.length; i++)
    threads[i].join();
Der Join wartet bis der Thread vor ihm fertig ist und startet den. Die Reihenfolge ist nicht garantiert^^

Die 2 Art:
Mit Future Objekt arbeiten und der Methode invokeAll() vom ThreadPoolExecutor. Dieses Future Objekt beinhaltet dann den Status des/(r) Threads.
Code:
List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();
// in deiner for-each jetzt
Future fTrack = executor.submit(tr); // oder submit((Runnable)tr); habs ned getestet
futures.add(fTrack);

for(Futures<Runnable> f : futures) {
    f.get(); // was passiert in dieser for-Schleife? Es wird ein Track nach dem anderen abgearbeitet (also wenn eins fertig ist dann das nächste)
}
Ich würde zusätzlich sagen, dass in deiner Tracks Klasse, deine download und progress Tasks ausgeführt werden sollten.


Edit: Mit der 2 Art selbst habe ich mich bis jetzt noch nicht wirklich beschäftigt(also was das starten des nächsten Threads wenn der jetzige Thread beendet wurde, angeht), deshalb meine recherche dazu:





Ich hoffe das hilft dir weiter!
XxharCs is offline  
Thanks
1 User
Old 02/02/2015, 17:19   #7
 
Zunft's Avatar
 
elite*gold: 0
Join Date: Mar 2013
Posts: 3,184
Received Thanks: 1,317
Danke, werde ich nachher ausprobieren wenn ich zuhause bin.

Bzgl. Der ersten methode:
Wenn ich die threads in ein arrax packe und diese mit einer schleife ausführe werden doch dann alle threads nacheinander ausgeführt also erst der download und danach die progressbar und nicht beide gleichzeitig oder ? Das heißt ich müsste entweder drei schleifen anlegen oder die threads in den einzelnen threads verschachteln also in download thread den progress thread aufrufen oder sehe ich das falsch ?

Edit: rein theoretisch sollte sich die GUI bei der methode auch aufhängen, das heißt die schleife(n) müssten auch wiederum in einem weiteren thread ausgelagert werden. Da sieht die zweite methode wesentlich eleganter aus, wobei auch hier so wie ich das sehe, ein weiterer thread erforderlich ist. Aber wie gesagt : ich probiere es nachher aus und melde mich nochmal.
Zunft is offline  
Old 02/02/2015, 20:17   #8
 
XxharCs's Avatar
 
elite*gold: 34
Join Date: Apr 2011
Posts: 1,475
Received Thanks: 1,227
Ja also, wie mein letzter Satz lautete vor dem Edit:
Quote:
Ich würde zusätzlich sagen, dass in deiner Tracks Klasse, deine download und progress Tasks ausgeführt werden sollten.
Weil eigentlich müssten die Prozente nicht mehr stimmen wenn du das in 3 verschiedenen Threads machst. Du kannst nicht garantieren ob jetzt dein "download" oder "progress"-Task zuerst fertig sein wird, mache das am besten in der Track Klasse oder in der Youtube Klasse und von dort aus benachrichtigst du deine GUI das sich was geändert hat und somit die Progressbar ändert. (Da würde eigentlich das Observer Pattern/Prinzip ins Spiel kommen)
XxharCs is offline  
Thanks
1 User
Old 02/02/2015, 21:31   #9
 
Zunft's Avatar
 
elite*gold: 0
Join Date: Mar 2013
Posts: 3,184
Received Thanks: 1,317
Vielen Dank für deine Hilfe ich habe es jetzt vorübergehend mit der 1. Methode gelöst, der Download funktioniert noch nicht optimal, das ist aber ein anderes Problem.

Für diejenigen, die an der Lösung interessiert sind, hier meine Lösung als Beispiel:

Tracks.java
Code:
    @Override
    protected Void call() throws Exception
    {
        updateProgress(100, 100); //Progressbar füllen
        percent = 0;
        Thread.sleep(1000); //1 Sekunde warten
        
        return null;
    }
Controller.java
Code:
Runnable[] threads = new Runnable[dwtable.getItems().size()]; //Lege ein Array für die Runnables aus Tracks an

Task startprocess = new Task<Void>() {
            @Override
            public Void call() {
                
                for(int i = 0; i < threads.length; i++)
                {
                    Thread thread1 = new Thread((Runnable) threads[i], "Track"); //Es wird nun für das Runnable ein Thread angelegt
                    try {          
                        thread1.start(); //Thread starten
                        thread1.join(); //Warten, bis dieser beendet wurde
                        
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
                    
                return null;
            }
        };

int z = 0;

for(Track tr : dwtable.getItems()) 
        {
                        
            try {

                System.out.println("Füge Thread " + z + " zu Array hinzu");
                
                threads[z] = (Runnable) tr;
                
                z++;
               
                
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
Zunft is offline  
Thanks
2 Users
Old 02/02/2015, 21:57   #10

 
snow's Avatar
 
elite*gold: 724
Join Date: Mar 2011
Posts: 10,480
Received Thanks: 3,319
Danke für das Posten deiner Lösung.

#closed (on request)
snow is offline  
Closed Thread


Similar Threads Similar Threads
[HELP] Erkennen wenn Programm Beendet wird. (Task Manager etc)
03/15/2014 - AutoIt - 13 Replies
Wie mach ich das das mein tool mir eine MsgBox absendet wenn der Prozess Test.exe über den Task Manager geschlossen wird? Hab das Problem mit MySQL. Register, Login und alles klappt nur wenn ich es über den Tast manager schließe führt er die Funktion _Logout() nicht aus wie kann man das ändern. Danke im vorraus!
Wenn ich Putty schließe beendet sich mein TS3 Server
12/26/2011 - Main - 6 Replies
Moin Leute, wie oben beschrieben habe ich ein problem mit meinem ts3 server der über nen root läuft. und wenn ich den ts3 server am laufen habe und mein putty programm beende, beendet sich auch der ts3 server. Ich bedanke mich im vorraus für die hilfe und hoffe ich bin in dem Bereich richtig. lg
While schleife pausieren und wieder fortsetzen!
06/16/2010 - AutoIt - 6 Replies
Hallo, ich möchte mein Script pausieren können mit "p" bzw. beenden mit "x" leider bin ich trotz diverser Suchaktionen noch nicht schlauer geworden vlt. kann mir jemand helfen MfG
Flyff beendet sich wenn Gameguard zuende geladen ist
11/30/2007 - Flyff - 21 Replies
BITTE HELFEN DAS SPIEL FLYFF macht update dann starte ich dann kommt game gaurd ladet danach geht es zu
Hmm Aapplikation wird beendet wenn ich das
10/04/2005 - Main - 1 Replies
...Terminal aus mache. Also ich folgendes problem auf linux, sobald ich z.b einen server eröffnet habe in einem terminal und dann das terminal zu machen beendet er auch automatisch den server... Mit crontabs probier ich gerade rum ab anscheinend muss dafür auch das terminal auf bleiben.



All times are GMT +2. The time now is 02:25.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.