问题背景
最近我想要实现一个这样的功能:在线程运行超过一段时间之后就向主程序抛出一个异常,并停止这个线程。
其具体的应用场景是一个任务由多个子任务组成,每个子任务单独一个线程,如果某个子任务长时间未完成就认为这个子任务失败(可能是因为网络原因卡死了),就需要把这个线程结束掉,然后等待调度器重新运行这个子任务。
最初的解决方案及问题
最开始我们参考了网上最常见的解决办法,就是使用ExecutorService+Future,使用Future类的get方法来实现。但是后面实际部署上去之后发现,线程超时的异常被截获到了,但是线程依然在运行。
即使是使用了future.cancel和executorService.shutdown,正在运行的线程也不会停止,可以通过以下的示例代码来验证:
ExecutorService executorService= Executors.newSingleThreadExecutor();
Future<Object> future=executorService.submit(()->{
while (true){
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("Test");
}
// return null;
});
try {
Object ret=future.get(3, TimeUnit.SECONDS);
System.out.println("Got it");
}catch (Exception e){
while(!future.cancel(false)){
System.out.println("Cancel failed");
}
System.err.println("Error "+future.isCancelled());
e.printStackTrace();
}finally {
executorService.shutdown();
}
修改后的解决方案
个人推测应该是不存在可以强行停止线程的api,我们能做的只能是使用一个flag让线程自己停止运行,这个flag可以考虑使用executorService.isShutdown(),这个具体怎么做就得具体问题具体分析了,以下是修改后的示例代码:
ExecutorService executorService= Executors.newSingleThreadExecutor();
Future<Object> future=executorService.submit(()->{
while (!executorService.isShutdown()){
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("Test");
}
return null;
});
try {
Object ret=future.get(3, TimeUnit.SECONDS);
System.out.println("Got it");
}catch (Exception e){
while(!future.cancel(false)){
System.out.println("Cancel failed");
}
System.err.println("Error "+future.isCancelled());
e.printStackTrace();
}finally {
executorService.shutdown();
}
标签:java,System,future,线程,shutdown,println,executorService,out
From: https://www.cnblogs.com/qzero233/p/18299874