2011-01-11 9 views
2

Ich habe eine Funktion, die eine Weile dauert, und will einen Wartebildschirm anzuzeigen:Wie die Semaphore in Java verwenden

Loading.showSplash("Working...");   

for (FileListRow row : model.getList()) { 
    performAction(row); 
} 

Loading.hideSplash(); 

Das Problem ist, dass der perform (row); scheint vor dem Ladebildschirm ausgeführt zu werden und damit den Zweck zu besiegen.

Hilfe zur Lösung des Problems, damit der wartende Bildschirm angezeigt wird, bevor der Rest ausgeführt wird, und um zu erzwingen, dass die Funktion beendet wird, bevor der Wartescreen verschwindet.

Antwort

1

Versuchen Sie es mit einem Schuss. Sie sollten den gesamten Code, der GUI-Updates durchführt, vom Event Dispatch Thread (EDT) aufrufen. Swing ist nicht threadsicher.

 

SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        Loading.showSplash("Working..."); 
       } 
      }); 

new Thread(new Runnable(){ 
       public void run(){ 
        for (FileListRow row : model.getList()) 
        { 
         performAction(row); 
        } 
       } 
      }).start(); 

Loading.hideSplash(); 
 
+0

Funktioniert nicht. Tatsächlich wird der Ladebildschirm jetzt nicht einmal angezeigt. Sobald die von mir ausgeführte Funktion vollständig ausgeführt ist, erscheint der Ladebildschirm. – user512684

+0

Versuchen Sie, die for-Schleife in einem eigenen Thread auszuführen. – user489041

+0

Dies wartet nicht auf das Beenden des Aktions-Threads vor dem Aufruf von 'hideSlash()'. – unholysampler

1

Kann ich annehmen, dass dies ein Swing-Programm ist?

Wenn ja, dann sieht es so aus, als würden Sie Ihre lang andauernden Vorgänge im Ereignisversand-Thread ausführen. Das ist eine schlechte Idee; Sie sollten alle lang andauernden Operationen auf einem Workert-Thread ausführen. Weitere Informationen finden Sie unter Java tutorial.

Und wenn Sie lang laufenden Operationen auf einem Hintergrund-Thread nicht durchführen, Ihre definitiv nicht wollen eine Semaphore verwenden, um den GUI-Thread, bis diese Operationen auszusetzen komplett - oder sogar bis sie beginnen. Der GUI-Thread sollte frei laufen können und Ereignisse verschicken, oder Ihre Benutzeroberfläche wird "Lags" haben, was für die Benutzer lästig ist. Wie andere Poster angegeben haben, kann Ihr Worker-Thread SwingUtilities.invokeLater() verwenden, um die Benutzeroberfläche zu aktualisieren.

+0

Ja, es ist ein Swing-Programm. Gute Kommentare danke. Ich gehe durch das Tutorial und sehe, wie ich den Code so reorganisieren kann, dass die Long Running-Funktion in einem Worker-Thread ist. – user512684

1

Ich gehe davon aus, dass Sie eine Swing-Anwendung entwickeln. Lesen Sie das Javadoc der SwingWorker-Klasse: http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html. Die Idee ist zu 1. Zeigen Sie Ihren Begrüßungsbildschirm 2. Starten Sie einen Thread, der alle Ihre Aktionen im Hintergrund ausführt. 3. Wenn die Hintergrundoperationen beendet sind, blenden Sie den Begrüßungsbildschirm aus

Der SwingWorker kümmert sich darum. Beachten Sie jedoch, dass die Hintergrundoperationen möglicherweise keine Swing-bezogene Komponente oder Klasse verwenden, da sie nicht Thread-sicher sind und im Ereignisversand-Thread (EDT) ausgeführt werden müssen.

Ein anderer, einfacherer Ansatz wäre, Ihren Begrüßungsbildschirm anzuzeigen und dann SwingUtilities.invokeLater zu verwenden, um Ihre Operationen auszuführen und den Begrüßungsbildschirm auszublenden. Auf diese Weise wird alles auf dem EDT ausgeführt, aber der Begrüßungsbildschirm wird angezeigt, bevor die anderen Operationen ausgeführt werden. Beachten Sie jedoch, dass bei dieser Technik die Anwendungs-GUI nicht mehr reagiert, bis der Startbildschirm ausgeblendet wird.

+0

Hum ... interessant. Es könnte tatsächlich ein anderer Ansatz sein. Das Hauptziel der Anzeige des Wartescreens ist nur, dass die Benutzer nicht ausflippen und überall klicken. Wenn die Anwendungs-GUI nicht reagiert, bis der Begrüßungsbildschirm ausgeblendet ist, ist dies eigentlich nicht notwendig. Ich habe das Tutorial und Ihren Link gelesen und bin mit dem Konzept vertraut. Jetzt geht es darum, den Code zu ändern, um genau das zu tun. – user512684

+0

+1 Hier ist ein einfaches 'SwingWorker' Beispiel http://stackoverflow.com/questions/4637725 – trashgod