How to use the Semaphore in Java
I have a function that takes a while and want to display a waiting screen :
Loading.showSplash("Working...");
for (FileListRow row : model.getList()) {
performAction(row);
}
Loading.hideSplash();
The problem is that the performAction(row); seems to be executed before the loading screen and hence it defeat the purpose.
Any help on solving this to force the waiting screen to show before the rest is executed a开发者_JS百科nd to force the function to finish before the waiting screen goes away.
Can I assume this is a Swing program?
If yes, then it looks like you're performing your long-running operations on the event dispatch thread. This is a bad idea; you should perform all long-running operations on a workert hread. See the Java tutorial for more information.
And if you do perform long-running operations on a background thread, your definitely do not want to use a semaphore to suspend the GUI thread until those operations complete -- or even until they start. The GUI thread should be allowed to run freely and dispatch events, or your UI will have "lags," which are annoying to users. As other posters have indicated, your worker thread can use SwingUtilities.invokeLater()
to update the UI.
Try giving this a shot. You should call all code that does GUI updates from the Event Dispatch Thread (EDT). Swing is not thread safe.
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();
I'll assume you are developing a Swing application. Read the javadoc of the SwingWorker class : http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html. The idea is to 1. display your splash screen 2. start a thread which performs all your actions in the background. 3. when the background operations are finished, hide the splash screen
The SwingWorker takes care of this. Note however that the background operations may not use any Swing-related component or class, since they're not thread-safe and must execute in the event dispatch thread (EDT).
Another, simpler approach would be to display your splash screen, and then use SwingUtilities.invokeLater to perform your operations and hide the splash screen. This way, everything will be done on the EDT, but the splash screen will be displayed before the other operations are performed. Note however that with this technique, the application GUI will be unresponsive until the splash screen is hidden.
精彩评论