Це працює
- Він походить від SingleThreadExecutor, але ви можете легко адаптувати його
- Java-код Lamdas 8, але його легко виправити
Це створить Виконавця з єдиною ниткою, який може отримати багато завдань; і чекатиме завершення поточного виконання, щоб розпочати наступне
У разі помилки або виключення uncaughtExceptionHandler зловить його
публічний заключний клас SingleThreadExecutorWithExceptions {
public static ExecutorService newSingleThreadExecutorWithExceptions (final Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
ThreadFactory factory = (Runnable runnable) -> {
final Thread newThread = new Thread (запускається, "SingleThreadExecutorWithExceptions");
newThread.setUncaughtExceptionHandler ((фінальна різьба Thread, остаточна метальна передача) -> {
uncaughtExceptionHandler.uncaughtException (caugthThread, кидається);
});
повернути новийTheread;
};
повернути нове FinalizableDelegatedExecutorService
(новий ThreadPoolExecutor (1, 1,
0L, TimeUnit.MILLISECONDS,
нова LinkedBlockingQueue (),
фабрика) {
захищена порожнеча afterExecute (Біг, що можна запустити, кидається) {
super.afterExecute (працює, перекидається);
if (кидаюча == null && runnable instanceof Future) {
спробуйте {
Майбутнє майбутнє = (Майбутнє), що працює;
якщо (future.isDone ()) {
future.get ();
}
} улов (CancellationException ce) {
перекидний = ce;
} улов (ExecutionException ee) {
киданий = ee.getCause ();
} улов (InterruptException, тобто) {
Thread.currentThread (). Interrupt (); // ігнорувати / скидати
}
}
if (кидаюча! = null) {
uncaughtExceptionHandler.uncaughtException (Thread.currentThread (), кидається);
}
}
});
}
приватний статичний клас FinalizableDelegatedExecutorService
розширює DelegatedExecutorService {
FinalizableDelegatedExecutorService (виконавець ExecutorService) {
супер (виконавець);
}
захищена недійсна фіналізація () {
super.shutdown ();
}
}
/ **
* Клас обгортки, який відкриває лише методи ExecutorService
* реалізації ExecutorService.
* /
приватний статичний клас DelegatedExecutorService розширює AbstractExecutorService {
приватний кінцевий ExecutorService e;
DelegatedExecutorService (виконавець ExecutorService) {e = виконавець; }
публічне недійсне виконання (команда Runnable) {e.execute (команда); }
public void shutdown () {e.shutdown (); }
загальнодоступний список shutdownNow () {return e.shutdownNow (); }
public boolean isShutdown () {return e.isShutdown (); }
public boolean isTerminated () {return e.isTerminated (); }
публічне булеве очікування випробування (тривалий час очікування, одиниця TimeUnit)
кидки InterruptedException {
повернути e.awaitTermina (таймаут, одиниця);
}
публічне подання на майбутнє (завдання, яке можна виконати) {
повернути e.submit (завдання);
}
публічне подання у майбутнє (завдання, що викликається) {
повернути e.submit (завдання);
}
публічне подання на майбутнє (виконання завдання, результат T) {
повернути e.submit (завдання, результат);
}
загальнодоступний список> invokeAll (Колекція> завдання)
кидки InterruptedException {
повернути e.invokeAll (завдання);
}
загальнодоступний список> invokeAll (Колекція> завдання,
довгий час очікування, одиниця TimeUnit)
кидки InterruptedException {
повернути e.invokeAll (завдання, тайм-аут, одиниця);
}
public T invokeAny (Колекція> завдання)
кидає InterruptedException, ExecutionException {
повернути e.invokeAny (завдання);
}
public T invokeAny (Колекція> завдання,
довгий час очікування, одиниця TimeUnit)
кидає InterruptException, ExecutionException, TimeoutException {
повернути e.invokeAny (завдання, тайм-аут, одиниця);
}
}
приватний SingleThreadExecutorWithExceptions () {}
}