Wednesday, November 28, 2018

java - ExecutorService workStealingPool and cancel method



Can you think about any reason why this code doesn't work and always outputs "finished", but the second example works without any problems. I'm using latest JDK (8u45).




public static class MyClass implements Runnable {

@Override

public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
return;
}
System.out.println("Finished");
}


public static void main(String[] args) {
// spot the difference ->
ExecutorService executorService = Executors.newWorkStealingPool(4);
Future future = executorService.submit(new MyClass());
Thread.sleep(100);
future.cancel(true);
}
}



And the following example works flawlessly:




public static class MyClass implements Runnable {

@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {

System.out.println("Interrupted");
return;
}
System.out.println("Finished");
}

public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new MyClass());
Thread.sleep(100);

future.cancel(true);
}
}


EDIT: Added return and updated sleep times and another example.


Answer



It's simpler than I thought originally. The problem is that work-stealing-pool is internally using ForkJoinPool and ForkJoinTask doesn't support cancel(true) and therefore it's not possible to cancel task after the task is started.



See javadoc documentation (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinTask.html):




   mayInterruptIfRunning - this value has no effect in the default implementation 
because interrupts are not used to control cancellation.

No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...