Gonen I
Gonen I

Reputation: 6107

Why can't I cancel my executor submited job?

I'm unsuccessfully trying to cancel a thread submitted with this code

  ExecutorService executor = Executors.newSingleThreadExecutor();
  Future<Object> future = executor.submit(()-> {while(true) { System.out.println("Thread"); Thread.yield();} } );
  Thread.sleep(3000);
  future.cancel(true);
  executor.shutdown();

but the thread stays running. When sleep is used instead of yield, the thread does get cancelled. For example this does cancel the thread:

  ExecutorService executor = Executors.newSingleThreadExecutor();
  Future<Object> future = executor.submit(()-> {while(true) { System.out.println("Thread"); Thread.sleep(1000);} } );
  Thread.sleep(3000);
  future.cancel(true);
  executor.shutdown();

What's going on? Am I missing something in the documentation?

Upvotes: 2

Views: 331

Answers (2)

Ravindra Ranwala
Ravindra Ranwala

Reputation: 21124

Your first task is NOT responsive to interruption. But the second task is responsive because Thread.sleep is a blocking method which is responsive to interruption. One way to solve the issue is by making your task responsive to interruption. Here's how it looks.

Future<?> future = executor.submit(() -> {
    while (!Thread.currentThread().isInterrupted())
        System.out.println("Thread");
});

Moreover Thread.yield is just a scheduler hint to yield its current use of a processor. This operation is platform dependent and should not be used in practice. Hence I have removed it from my answer.

Upvotes: 3

Jude Niroshan
Jude Niroshan

Reputation: 4460

If your intention is to stop all submitted tasks you could use

executor.shutdownNow();

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()


As already mentioned in the comments section of the question, it is the difference between .sleep(1000) and .yield() behaviour for interrupt calls

Upvotes: 0

Related Questions