ExecutorService mit Timeout für unterbrechbare Aufgaben
Bei der gleichzeitigen Ausführung von Aufgaben ist es oft wünschenswert, über einen Mechanismus zu verfügen, um Aufgaben, die einen festgelegten Wert überschreiten, ordnungsgemäß zu unterbrechen Time-out. Dies ist besonders nützlich in Situationen, in denen lang laufende Aufgaben zu Anwendungsabstürzen oder Leistungsproblemen führen können.
Implementieren eines TimeoutExecutorService
Hier ist eine Implementierung eines TimeoutThreadPoolExecutors, der den erweitert Standard-ThreadPoolExecutor und enthält eine Zeitüberschreitung Feature:
class TimeoutThreadPoolExecutor extends ThreadPoolExecutor { private final long timeout; private final TimeUnit timeoutUnit; private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); private final ConcurrentMap<Runnable, ScheduledFuture> runningTasks = new ConcurrentHashMap<>(); public TimeoutThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, long timeout, TimeUnit timeoutUnit) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); this.timeout = timeout; this.timeoutUnit = timeoutUnit; } // Override methods to implement timeout behavior @Override protected void beforeExecute(Thread t, Runnable r) { if (timeout > 0) { ScheduledFuture scheduled = timeoutExecutor.schedule(new TimeoutTask(t), timeout, timeoutUnit); runningTasks.put(r, scheduled); } } @Override protected void afterExecute(Runnable r, Throwable t) { ScheduledFuture timeoutTask = runningTasks.remove(r); if (timeoutTask != null) { timeoutTask.cancel(false); } } // Timeout task to interrupt threads class TimeoutTask implements Runnable { private final Thread thread; public TimeoutTask(Thread thread) { this.thread = thread; } @Override public void run() { thread.interrupt(); } } }
Verwendung:
Um den TimeoutThreadPoolExecutor zu verwenden, können Sie ihn einfach mit einem Timeout-Wert instanziieren:
TimeoutThreadPoolExecutor executor = new TimeoutThreadPoolExecutor( 4, // corePoolSize 8, // maximumPoolSize 1, // keepAliveTime TimeUnit.SECONDS, // timeUnit new LinkedBlockingQueue<>(), // workQueue 5, // timeout TimeUnit.SECONDS // timeoutUnit );
Dann , Aufgaben wie gewohnt an den Ausführenden übergeben:
executor.submit(() -> { // long-running task });
Wenn eine Aufgabe länger dauert als das angegebene Zeitlimit überschreitet, wird der Thread, der die Aufgabe ausführt, unterbrochen, wodurch die Aufgabe ordnungsgemäß beendet wird.
Alternative Lösung
Ein weiterer Ansatz zum Implementieren eines Zeitlimits für eine Aufgabe besteht darin, den ScheduledExecutorService zu verwenden, wie in der Antwort vorgeschlagen. Dabei geht es darum, die Aufgabe als Callable einzureichen und die erstellte Zukunft beizubehalten. Anschließend kann eine zweite Aufgabe geplant werden, um die Zukunft nach einer bestimmten Zeitspanne abzubrechen und so die Aufgabe effektiv zu unterbrechen.
Das obige ist der detaillierte Inhalt vonWie kann ich ein Timeout für unterbrechbare Aufgaben in einem ExecutorService implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!