Как использовать Семафор в Java - PullRequest
2 голосов
/ 11 января 2011

У меня есть функция, которая занимает некоторое время и я хочу отобразить экран ожидания:

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

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

Loading.hideSplash(); 

Проблема в том, что executeAction (строка); кажется, выполняется перед загрузкой экрана и, следовательно, это победить цель.

Любая помощь в решении этой проблемы - заставить экран ожидания отображаться до того, как выполнятся остальные, и заставить функцию завершиться до того, как экран ожидания исчезнет.

Ответы [ 3 ]

1 голос
/ 11 января 2011

Могу ли я предположить, что это программа Swing?

Если да, то похоже, что вы выполняете свои длительные операции в потоке диспетчеризации событий.Это плохая идея;Вы должны выполнять все длительные операции на рабочем месте.См. Java-учебник для получения дополнительной информации.

И если вы выполняете длительные операции с фоновым потоком, вы определенно не хотите использовать семафор дляприостановить поток графического интерфейса пользователя до тех пор, пока эти операции не завершатся - или даже до их запуска.Поток GUI должен иметь возможность свободно запускать и отправлять события, иначе ваш пользовательский интерфейс будет иметь «лаги», которые раздражают пользователей.Как указывали другие авторы, ваш рабочий поток может использовать SwingUtilities.invokeLater() для обновления пользовательского интерфейса.

1 голос
/ 11 января 2011

Я предполагаю, что вы разрабатываете приложение Swing.Прочитайте Javadoc класса SwingWorker: http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html. Идея состоит в том, чтобы 1. отобразить заставку 2. запустить поток, который выполняет все ваши действия в фоновом режиме.3. когда фоновые операции завершены, скройте заставку

SwingWorker позаботится об этом.Однако обратите внимание, что фоновые операции могут не использовать какой-либо компонент или класс, относящиеся к Swing, поскольку они не являются поточно-ориентированными и должны выполняться в потоке диспетчеризации событий (EDT).

Другой, более простой подход заключается вотобразить заставку, а затем использовать SwingUtilities.invokeLater для выполнения ваших операций и скрыть заставку.Таким образом, все будет сделано на EDT, но заставка будет отображаться до выполнения других операций.Однако обратите внимание, что при использовании этого метода графический интерфейс приложения не будет отвечать до тех пор, пока заставка не будет скрыта.

1 голос
/ 11 января 2011

Попробуйте дать этому шанс. Вы должны вызывать весь код, который выполняет обновления GUI, из потока диспетчеризации событий (EDT). Качели не безопасны для потоков.


 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(); 

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...