Лично мне не нравится первый подход, вероятно, из-за interrupt
в основном.Что делать, если кто-то что-то вызывает и прерывает эту тему?Вы будете запускать произвольный код, вероятно, не лучшая идея.Кроме того, когда вы прерываете, вы фактически заполняете трассировку стека цепочками исключений, это самая дорогая часть из создаваемого исключения.
Но предположим, что вас не волнует второй пункт, и вы полностью контролируете первый;Вероятно, в этом подходе нет ничего плохого.
Теперь разница между Conditional
и wait/notify
в этом примере довольно мала.Я не знаю внутренних деталей и которые могут быть быстрее или лучше, но в целом Conditional
предпочтительнее;главным образом по той причине, что ее легче читать, по крайней мере, для меня.Также Conditional
может быть взято из другой блокировки все время, в отличие от synchronized
.
Другие преимущества (не связанные здесь): вы можете создать несколько условий, таким образом пробуждая только нужную нить ;в отличие от notifyAll
например.Тогда есть методы с истечением срока действия, такие как awaitUntil(Date)
или await(long, TimeUnit)
или awaitNanos
.Есть даже метод, который будет await
и вообще игнорировать interrupts
: awaitUninterruptibly
.
При этом вам не нужно lock::unlock
после await
, так как документация довольно яснав этом отношении:
Блокировка, связанная с этим условием, снимается атомарно ...
Гораздо более простой подход был бы:
static class AsyncExecutor {
private static final ExecutorService service = Executors.newSingleThreadExecutor();
public static void execute(Runnable runnable) {
service.execute(runnable);
}
}