Я хотел бы выполнить некоторые работы в фоновом режиме с ограничением по времени. Дело в том, что я не хочу блокировать основной поток.Тайм-аут для ExecutorService без блокировки основного потока
Наивная реализация должна иметь два исполнителя. Один для планирования/таймаута, а второй - для выполнения работы.
final ExecutorService backgroundExecutor = Executors.newSingleThreadExecutor();
final ExecutorService workerExecutor = Executors.newCachedThreadExecutor();
backgroundExecutor.execute(new Runnable() {
public void run() {
Future future = workerExecutor.submit(new Runnable() {
public void run() {
// do work
}
});
try {
future.get(120 * 1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
logger.error("InterruptedException while notifyTransactionStateChangeListeners()", e);
future.cancel(true);
} catch (ExecutionException e) {
logger.error("ExecutionException", e);
} catch (TimeoutException e) {
logger.error("TimeoutException", e);
future.cancel(true);
}
}
});
Есть ли другие решения?
Одним из упрощений будет один пул из двух потоков, один из которых выполнит задание, а другой ждет его. Это, по крайней мере, экономит внутренний пул, но в остальном это не очень помогает. – Gray
Можно ли одновременно выполнять задачи как для Таймера, так и для Исполнителя? Сначала вы получите в run(), и поэтому где-то понадобится блокировка или синхронизация для арбитража между тайм-аутом и завершенной задачей, чтобы в каждом случае можно было предпринять правильные действия. Хм .. не уверен. –
Поскольку вы игнорируете результат Future.get() в своем коде, я задаюсь вопросом, действительно ли вам нужно ждать результата в каком-то потоке? –