Reputation: 6107
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
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
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