Качайте "блокировку", я думаю, что мне нужно нить, но не уверен, сколько - PullRequest
3 голосов
/ 30 января 2010

У меня есть небольшое java-приложение для эффективного "подхвата" произвольной коллекции файлов, определенных в ini-файле. Мой класс LogReader расширяет JFrame и выполняет тяжелую работу; чтение набора путей к файлам в вектор, а затем итерация по вектору, чтение каждого файла и добавление последних X строк каждого в текстовые области на вкладках JTabbedPane. Процесс создания вектора и итерации по файлам запускается щелчком JButton через ActionListener.

Чтение файлов работало нормально (и продолжает работать), но процесс чтения 20 файлов, некоторые из которых достигают 30 МБ, занимает некоторое время. Чтобы помочь скоротать это время, я решил добавить экран прогресса, на котором написано «Сейчас читаем файл № 3 из 26: c: \ logs \ superduper1.log» и так далее. Поэтому я создал другой класс, «SplashScreen», также расширяющий JFrame, и добавил JLabel, который будет указывать на прогресс. Класс SplashScreen имеет метод update (), который просто выполняет setText () для JLabel.

ActionListener на JButton вызывает RefreshLogs (), который выглядит примерно так:

vctFileStrings.clear();
tpMain.removeAll();
frmSplash.update("Loading Configuration"); //Update the label on the Splash Screen instance
BuildVectorOfLogs(strConfFile); //Read the collection of files into the vector
frmSplash.update("Reading Logs");
ReadLogs(); //read the files, updating the Splash Screen as we go

и затем ReadLogs () выполняет итерацию по вектору, читая файлы и создавая TabbedPane.

Однако я заметил, что при вызове RefreshLogs () из ActionListener заставка не обновляется. Однако, если я добавлю RefreshLogs () в конструктор первого фрейма, заставка будет работать, как и ожидалось (процесс обновления каждого файла). После некоторых экспериментов и чтения я думаю, что мне нужно создать рабочий поток, который читает файлы, одновременно обновляя заставку в очереди отправки событий.

Мои вопросы:
- Моя мысль верна? Есть ли какая-то простая альтернатива реализации потоков, которая позволила бы мне обновить заставку из метода, вызываемого ActionListener?
- Если бы это было лучше всего достигнуть с помощью потоков, то какой объем деятельности мне понадобится для потоков? Должен ли я поместить все операции ввода-вывода в файл в свой собственный поток? Должен ли я поместить действия GUI (обновления меток) в их собственный поток, чтобы они происходили отдельно от события нажатия JButton?

Ответы [ 3 ]

4 голосов
/ 30 января 2010

Я бы сказал: да, ваши мысли о переносе чтения больших файлов в отдельный поток верны. Вы никогда не должны выполнять длинные задачи в потоке диспетчеризации событий, поскольку, пока этот поток занят, графический интерфейс пользователя не отвечает, а приложение работает медленно.

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

У Sun есть учебник по SwingWorker .

3 голосов
/ 30 января 2010

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

Для этого вы можете использовать SwingWorker. Посмотрите на Использование Swing Worker Thread , который выглядит так, как вам нужно.

0 голосов
/ 30 января 2010

Одним из предложений для вас, чтобы выяснить, как это сделать, и в случае, если вы используете NetBeans или имеете доступ к NetBeans, является поиск по умолчанию шаблона Java Desktop Application .Он создает предварительно подключенное настольное приложение с индикатором выполнения, встроенным в строку состояния, которое будет автоматически обновляться при выполнении любого кода «Действие».Он использует API-интерфейс Action, который также предварительно настроен для работы в фоновом потоке.

Глядя на этот автоматически сгенерированный код, вы сможете правильно и легко реализовать его самостоятельно.

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