我想取消提交给ExecutorService的任务,从而允许相应的线程从队列中选择新的任务。取消java中的未来任务
现在这个问题已经在这个论坛上多次回答过......比如检查Thread.currentThread().interrupt()
或catch (InterruptedException e)
。但是如果控制流横跨多种方法,那么放这些检查会使代码笨拙。所以如果可能的话,请在java中提出一些优雅的方法来实现这个功能。
我面临的问题是future.cancel实际上不会取消任务。相反,它仅向正在执行的任务发送InterruptedException
,这是标记自己完成并释放线程的任务的责任。
所以我所做的就是只要在执行过程中的任何地方抛出异常,我就不得不放置下面的代码块,这显然看起来不太好!
if(e instanceof InterruptedException) {
throw e;
}
那么,如何实现在下面的代码片段此功能:
public class MonitoringInParallelExp {
public static void main(String[] args) throws InterruptedException {
MyClass1 myClass1 = new MyClass1();
ExecutorService service = Executors.newFixedThreadPool(1);
Future<String> future1 = service.submit(myClass1);
Thread.sleep(2000);
System.out.println("calling cancel in Main");
future1.cancel(true);
System.out.println("finally called cancel in Main");
service.shutdown();
}
}
class MyClass1 implements Callable<String> {
@Override
public String call() throws Exception {
try{
MyClass2 myClass2 = new MyClass2();
myClass2.method2();
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("call:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method1. " + e);
}
System.out.println("returning Myclass1.method1.exit");
return "Myclass1.method1.exit";
}
}
class MyClass2 {
public void method2() throws Exception{
try{
MyClass3 myClass3 = new MyClass3();
myClass3.method3();
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("method2:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method2. " + e);
// in case the exception isn't InterruptedExceptionm, do some work here
}
}
}
class MyClass3 {
public void method3() throws Exception{
try{
Thread.sleep(10000);
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("method3:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method3. " + e);
throw new MyException();
}
}
}
class MyException extends Exception {
}
future1.cancel(true)肯定会发送InterruptedException,因为主线程只睡2000ms,而method3需要10000ms才能完成。 现在method3将检查异常是否是instanceof InterruptedException或不是。如果是,那么它会将它传递给调用者(方法2)。 我不想在整个工作流程的任何地方保持这种检查,最终将其传递给MyClass1.call()方法。 在这个世界上有没有其他优雅的方式来实现这个功能? – gautam
@gautam - 使用回调机制。将对象传递给其他类并在InterruptedException期间捕获一个方法。对于回调机制,请参阅https://stackoverflow.com/questions/36449040/executing-java-callback-on-a-new-thread/36451028#36451028。 –