(обязательно прочитайте правку ниже, этот вопрос явно сбивает с толку, извините за это)
Вот типичный SwingUtilities.invokeLater
вызов:
SwingUtilities.invokeLater( new Runnable() {
public void run() {
...
}
} );
Теперь я хотел бы иметь то, что было бы SwingUtilities.invokeNowOrLaterIfEDT
.
Конечно, я мог бы использовать свой собственный служебный класс, например:
public static void invokeNowOrLaterIfEDT( @NotNull Runnable r ) {
if ( SwingUtilities.isEventDispatchThread() ) {
Thread t = new Thread( r );
t.start();
} else {
r.run();
}
}
но у этого есть недостаток, заключающийся в создании нового потока каждый раз, когда он вызывается из EDT (и приходится ждать, пока этот новый поток будет запланирован).
Другой способ сделать это — использовать один дополнительный поток, работающий в течение жизненного цикла приложения (который может быть лениво создан), используя некоторую блокирующую очередь для постановки в очередь Runnables
. Преимущество будет заключаться в том, что потоки не будут постоянно создаваться каждый раз, когда я вызываю такой метод из EDT.
Существует ли что-то подобное в API Java по умолчанию?
Что было бы лучше: просто создавать новый поток каждый раз, когда это вызывается из EDT, как в примере выше, или иметь один дополнительный поток, в котором Runnables
будет выполняться вне EDT, или что-то еще?
EDIT: точно так же, как SwingUtilities.invokeLater
может вызываться или не вызываться из EDT, метод, который я имел в виду, может вызываться или не вызываться из EDT. Это выполнение чего-то полностью асинхронного, что может быть вызвано или не вызвано действием пользователя в GUI/EDT. Я думаю, что SwingUtilities.invokeLater
очень удобно иметь возможность запускать что-то в EDT, не заботясь о том, когда вы вызываете его, находитесь ли вы в EDT или нет. И я думаю, что invokeNowOrLaterIfEDT(...)
, что я показал выше, очень удобен. Но я могу ошибаться в этом. Является ли потребность в таком методе сумасшедшей? Теперь я начинаю сомневаться!?
РЕДАКТИРОВАТЬ ВТОРОЕ: я совсем не ясно выразился, и я это понимаю, извините за это. То, что я хочу запускать асинхронно, а не из EDT, не является очень долгим процессом, и нет необходимости в каких-либо обновлениях, таких как индикатор выполнения или что-либо, показывающее, что происходит. Это также не проблема, если он однопоточный/в очереди (очевидно, я указал это в вопросе). Мне вовсе не нужен пул потоков для эффективного распределения нагрузки на различные ядра и т. д. Просто это небольшие вычисления, которые не нужно запускать в EDT и которые могут быть вызваны из EDT или нет. На самом деле это просто крошечные асинхронные вещи, которые я хочу выполнить вне EDT. Это не проблема, если все они поставлены в очередь в одном потоке и т. д.
Но теперь, благодаря вашим ответам, я также понимаю, что если бы такая вещь была реализована с использованием одного потока и очереди Runnable, то было бы очень легко выстрелить себе в ногу, вызвав такой служебный метод для долгих вычислений, который бы тогда все будет поставлено в очередь, а не правильно многопоточно.