ExecutorService-在指定的时间限制后杀死线程

问题描述 投票:0回答:2

我创建了ExecutorService并提交了工作。这项工作可能很耗时。因此,我给了timeout 2秒。如果执行时间超过2秒,我想杀死该线程。

public void threadTest() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try {
            executor.submit(() -> {
                try {
                    String threadName = Thread.currentThread().getName();
                    Thread.sleep(7000);
                    System.out.println("process completed after 7 seconds");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).get(2, TimeUnit.SECONDS);
        }catch (Exception e){
        }
        executor.shutdown();

    }

    public static void main(String[] args) throws Exception {
        System.out.println("main start");
        ThreadBreaker tb = new ThreadBreaker();
        tb.threadTest();
        System.out.println("main end");
    }

输出

main start
main end
process completed after 7 seconds

threadTest函数在2秒钟后退出,正如我预期的那样。但是提交的作业一直在运行。我想停止提交的任务,如果它不能在给定的超时时间内完成。

java threadpool runnable executorservice threadpoolexecutor
2个回答
0
投票

一旦您向executorService提交了任务,便有了Future对象。您可以通过Future.cancel(true)调用取消执行。

请记住,当在任务中进行准确的InterruptException处理时,可以取消正在运行的任务。

在上面的示例中:

 Thread.sleep(7000); 

将引发一个被中断的异常,您不应捕获它(或者,如果捕获到它,则会引发另一个异常)


0
投票

使用ExecutorService时,您无法自己杀死线程。 ThreadPool决定何时杀死Thread(通常,如果Thread被中断,可能会发生)。

在您的情况下,您应该抓住TimeoutException,而cancelFuture。如果您的“真实”任务响应中断(正确调用和处理InterruptedException),它将起作用。否则,您应该循环检查Thread.currentThread().isInterrupted()状态。您的示例代码如下所示:

public void threadTest() {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<?> submit = executor.submit(() -> {
        try {
            String threadName = Thread.currentThread().getName();
            Thread.sleep(7000);
            System.out.println("process completed after 7 seconds");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); //preserve interruption status. based on this ThreadPool's interruption Policy will decide what to do with the Thread
        }
    });

    try {
        submit.get(2, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace(); //handle this
    } catch (TimeoutException e) {
        submit.cancel(true); //cancel the task
    }
    executor.shutdown();

}

还请记住,如果您在ThreadPool中执行任务,并且在大多数情况下执行的操作可能来自InterruptedException,则应保留中断状态。

© www.soinside.com 2019 - 2024. All rights reserved.