-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
8u60, 9
A DESCRIPTION OF THE PROBLEM :
The documentation for Future talks about "cancellation" without really defining what that means.
The problem is that even if Future.cancel() returns true, this does not guarantee that the task will never run.
In fact, the task can continue to run (for arbitrarily long) after either/both of:
(a) Future.cancel() has returned true
(b) Future.get() has thrown CancellationException
Please clarify the API documentation to explicitly note that cancellation is "best effort" and that for a task which has already started running, Future.cancel() may return true even though the task can continue to run and complete normally.
Here's a test program that demonstrates the somewhat surprising behavior:
============== PROGRAM ===============
import java.util.concurrent.*;
public class xx {
public static void main(String[] args) throws Exception {
final ScheduledExecutorService e = Executors.newSingleThreadScheduledExecutor();
Future<?> f = e.submit(new Runnable() {
@Override
public void run() {
System.out.println("task started");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println("task completed");
}
});
Thread.sleep(1);
boolean b = f.cancel(false);
System.out.println("cancel() returned " + b);
try {
f.get();
System.out.println("get() returned normally");
} catch (Throwable t) {
System.out.println("get() threw " + t);
}
e.shutdownNow();
}
}
==============================================
Here's the output:
============== OUTPUT ===============
task started
cancel() returned true
get() threw java.util.concurrent.CancellationException
task completed
==============================================
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
More clarity about Future.cancel().
ACTUAL -
Not enough clarity about Future.cancel().
URL OF FAULTY DOCUMENTATION :
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
The documentation for Future talks about "cancellation" without really defining what that means.
The problem is that even if Future.cancel() returns true, this does not guarantee that the task will never run.
In fact, the task can continue to run (for arbitrarily long) after either/both of:
(a) Future.cancel() has returned true
(b) Future.get() has thrown CancellationException
Please clarify the API documentation to explicitly note that cancellation is "best effort" and that for a task which has already started running, Future.cancel() may return true even though the task can continue to run and complete normally.
Here's a test program that demonstrates the somewhat surprising behavior:
============== PROGRAM ===============
import java.util.concurrent.*;
public class xx {
public static void main(String[] args) throws Exception {
final ScheduledExecutorService e = Executors.newSingleThreadScheduledExecutor();
Future<?> f = e.submit(new Runnable() {
@Override
public void run() {
System.out.println("task started");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println("task completed");
}
});
Thread.sleep(1);
boolean b = f.cancel(false);
System.out.println("cancel() returned " + b);
try {
f.get();
System.out.println("get() returned normally");
} catch (Throwable t) {
System.out.println("get() threw " + t);
}
e.shutdownNow();
}
}
==============================================
Here's the output:
============== OUTPUT ===============
task started
cancel() returned true
get() threw java.util.concurrent.CancellationException
task completed
==============================================
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
More clarity about Future.cancel().
ACTUAL -
Not enough clarity about Future.cancel().
URL OF FAULTY DOCUMENTATION :
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
- links to
-
Review(master) openjdk/jdk/25880