Heim >Java >javaLernprogramm >Wie kann ich ein Timeout für unterbrechbare Aufgaben in einem ExecutorService implementieren?

Wie kann ich ein Timeout für unterbrechbare Aufgaben in einem ExecutorService implementieren?

DDD
DDDOriginal
2024-12-11 14:54:11835Durchsuche

How Can I Implement a Timeout for Interruptable Tasks in an ExecutorService?

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn