Как заставить SwingUtilities.invokeLater выполнять задачи быстрее?

Я использую SwingUtilities.invokeLater для обновления пользовательского интерфейса. Иногда задачи выполняются практически сразу после вызова invokeLater, но иногда на это уходит несколько секунд, чего хотелось бы избежать. Есть ли какие-то настройки, которые могут помочь мне в этом?

Я знаю, что задачи выполняются в потоке диспетчеризации событий AWT, но есть ли способ принудительно очистить очередь от него (вероятно, не очень хорошая идея) или каким-то образом добавить еще один поток AWT для параллельной работы или любое другое решение, которое может помочь с выполнением задач быстрее?

Можно ли вообще повлиять на это, или все, что я могу сделать, это просто создать несколько потоков демонов самостоятельно? Я хотел бы избежать этого.


person Bobby    schedule 01.12.2020    source источник
comment
Нет, вы не можете напрямую влиять на поток диспетчеризации событий AWT. Вы можете свести к минимуму объем кода в переопределении paintComponent или других обновлениях графического интерфейса.   -  person Gilbert Le Blanc    schedule 01.12.2020
comment
иногда это занимает несколько секунд .. почему? Это приложение. занимаетесь чем-нибудь еще в это время? Я подозреваю, что это случай ... иногда блокировки EDT.   -  person Andrew Thompson    schedule 01.12.2020
comment
Используйте профилировщик с представлением потоков, чтобы узнать, что делает поток обработчика событий в течение этих нескольких секунд. Я совершенно уверен, что он не простаивает, а выполняет другие задачи, запрошенные вашим приложением.   -  person Ralf Kleberhoff    schedule 01.12.2020


Ответы (2)


Есть вещи, которые нужно сделать в потоке обработчика событий. Swing не является потокобезопасным, и несоблюдение этого правила приводит к СТРАННЫМ вещам.

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

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

Приличный инструмент профилировщика будет полезен в этом процессе.

person Ralf Kleberhoff    schedule 01.12.2020

Вы пробовали SwingUtilities.invokeAndWait()? Похоже, вы не хотите, чтобы программа выполняла другие действия, связанные с операциями Swing, вы хотите, чтобы они выполнялись прямо сейчас.

Конечно, это на самом деле не приведет к тому, что они будут выполняться за меньшее количество циклов ЦП, и если есть вещи, уже поставленные в очередь для потока отправки, это не избавит их или что-то еще.

Есть также такие вещи, как загрузка изображений из файлов, которые могут выполняться синхронно или асинхронно — если вы пытаетесь устранить паузы, вы можете убедиться, что они выполняются так, как вы хотите.

person arcy    schedule 01.12.2020
comment
Спасибо Арси! Я попробовал это, и это сработало, но позже пользовательский интерфейс в некоторых других случаях стал заблокированным, поэтому, к сожалению, мне, вероятно, придется найти более сложное решение. - person Bobby; 02.12.2020
comment
Звучит как другой вопрос; Из вашего сообщения я не могу понять, имеет ли это какое-то отношение к блокировке или к тому, что вы имеете в виду под блокировкой. Если вы публикуете вопрос и получаете ответ, который отвечает на этот вопрос на SO, (ожидается? Традиционно?) щелкнуть галочку рядом с этим ответом, чтобы пометить его как ответ. Это влияет на рейтинги и так далее, я думаю об этом как о монете, используемой для оплаты ТАКОЙ полезности. - person arcy; 02.12.2020