Cancel future task in java

I want to cancel the task sent to the ExecutorService, which will allow the corresponding thread to select a new task from the queue.

Now this question has many answers in this forum .... for example, checking Thread.currentThread().interrupt() or catch (InterruptedException e) . But if the control flow covers several methods, then performing these checks makes the code awkward. Therefore, if possible, suggest some elegant ways in java to achieve this functionality.

The problem I am facing is that future.cancel does not actually cancel the task. Instead, it simply throws an InterruptedException executing task and is responsible for flagging itself and freeing the thread.

So what I did was that I had to put a block of code below whenever an exception was thrown at any place in the execution, which obviously does not look good!

 if(e instanceof InterruptedException) { throw e; } 

So, how to achieve this functionality in the following code fragment:

 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 { } 
+5
source share
1 answer

It doesnโ€™t matter if you Callable or not, because at this point it is too late

 try{ MyClass2 myClass2 = new MyClass2(); myClass2.method2(); } catch (Exception e){ 

Your call future1.cancel(true); after Thread.sleep(2000) does not actually cancel the current task (in this case, your method2 call), this means that it had to be canceled before it started.

Docs point out that https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)

Trying to cancel this task. This attempt will fail if the task is already completed, already canceled or cannot be canceled for any other reason. If successful, and this task did not start when the cancel was called, this task should never be started. If the task is already running, the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted when it tries to stop the task.

If you want to cancel the current task, you want to use the volatile boolean flag or something similar.

+4
source

Source: https://habr.com/ru/post/1269440/


All Articles