我创建了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秒钟后退出,正如我预期的那样。但是提交的作业一直在运行。我想停止提交的任务,如果它不能在给定的超时时间内完成。
一旦您向executorService提交了任务,便有了Future对象。您可以通过Future.cancel(true)调用取消执行。
请记住,当在任务中进行准确的InterruptException处理时,可以取消正在运行的任务。
在上面的示例中:
Thread.sleep(7000);
将引发一个被中断的异常,您不应捕获它(或者,如果捕获到它,则会引发另一个异常)
使用ExecutorService
时,您无法自己杀死线程。 ThreadPool决定何时杀死Thread
(通常,如果Thread
被中断,可能会发生)。
在您的情况下,您应该抓住TimeoutException
,而cancel
是Future
。如果您的“真实”任务响应中断(正确调用和处理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
,则应保留中断状态。