1

I have a method that creates a future:

@Service
public class TestService {
    @Async
    public Future<TestClass> testCancelFuture() throws InterruptedException  {
        TestClass testClass = new TestClass();
        testClass.loop();
        return new AsyncResult<TestClass>(testClass);
    }
}

And this is my TestClass

public class TestClass {
    public void loop() throws InterruptedException  {
        for (int i=0; i<100; i++) {
            System.out.println("[" + i + "] loop");
            Thread.sleep(1000);
        }
    }
}

Now, I invoke the method testCancelFuture and cancel it:

@Controller
@RequestMapping("/test")
public class TestController() {
    @Autowired
    TestService testService;

    @RequestMapping(method = RequestMethod.GET) 
    public String testMethod () throws InterruptedException {
        Future<TestClass> test = testService.testCancelFuture();
        test.cancel(true);
        return "test";
    }
}

I would expect the loop to stop , as i cancel the future soon after starting it. However the loop keep going. So, how can I stop the loop in the future ?

Tk421
  • 6,196
  • 6
  • 38
  • 47

1 Answers1

3

Cancelling / interrupting a running task is never guaranteed. Have a read at Thread.interrupt() method description:

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

If your task regulary invokes one of those methods listed then there's a higher chance you'll get more responsive cancellation.

Otherwise the thread might just keep running as if the cancellation is ignored. One way to improve this is to split your task into smaller chunks that checks whether it should keep running in between.

gerrytan
  • 40,313
  • 9
  • 84
  • 99