(обязательно прочитайте правку ниже, этот вопрос явно сбивает с толку, извините)
Вот типичный 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, то было бы очень легко выстрелить себе в ногу, долго вызывая такой служебный метод вычисление, которое затем будет поставлено в очередь вместо правильно многопоточного.