[concurrency-interest] Future.isCompletedNormally Future.isCompletedAbnormally

Martin Buchholz martinrb at google.com
Wed Mar 4 22:24:45 EST 2015


ForkJoinTask is a Future implementation with existing methods
isCompletedNormally isCompletedAbnormally.

We could make these methods on Future itself with (inefficient) default
implementations and efficient implementations on FutureTask and
CompletableFuture.

Worth doing?

Here's a v0.1:

Index: CompletableFuture.java
===================================================================
RCS file:
/export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.158
diff -u -r1.158 CompletableFuture.java
--- CompletableFuture.java    17 Jan 2015 20:05:02 -0000    1.158
+++ CompletableFuture.java    5 Mar 2015 03:18:19 -0000
@@ -2314,6 +2314,32 @@
     }

     /**
+     * Returns {@code true} if this CompletableFuture exceptionally and
was not cancelled.
+     *
+     * @return {@code true} if this CompletableFuture completed
exceptionally and was not cancelled
+     */
+    public final boolean isCompletedAbnormally() {
+        Object r;
+        return ((r = result) instanceof AltResult)
+            && r != NIL
+            && !(((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        Object r;
+        return (r = result) != null
+            && (r == NIL
+                || !(r instanceof AltResult));
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
Index: Future.java
===================================================================
RCS file:
/export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.40
diff -u -r1.40 Future.java
--- Future.java    17 Feb 2015 18:55:39 -0000    1.40
+++ Future.java    5 Mar 2015 03:18:19 -0000
@@ -110,6 +110,66 @@
     boolean isDone();

     /**
+     * Returns {@code true} if this task completed by throwing an
exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    default boolean isCompletedAbnormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                } catch (ExecutionException e) {
+                    return true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    default boolean isCompletedNormally() {
+        if (!isDone() || isCancelled())
+            return false;
+        // Support Future implementations that throw
+        // InterruptedException even when result is available.
+        boolean interrupted = false;
+        try {
+            retry: for (;;) {
+                try {
+                    get();
+                    return true;
+                } catch (ExecutionException e) {
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                    continue retry;
+                }
+                return false;
+            }
+        } finally {
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
      * Waits if necessary for the computation to complete, and then
      * retrieves its result.
      *
Index: FutureTask.java
===================================================================
RCS file:
/export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java,v
retrieving revision 1.111
diff -u -r1.111 FutureTask.java
--- FutureTask.java    5 Mar 2015 00:32:52 -0000    1.111
+++ FutureTask.java    5 Mar 2015 03:18:19 -0000
@@ -133,6 +133,32 @@
         return state != NEW;
     }

+    /**
+     * Returns {@code true} if this task completed by throwing an
exception.
+     *
+     * @return {@code true} if this task completed by throwing an exception
+     */
+    public final boolean isCompletedAbnormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == EXCEPTIONAL;
+    }
+
+    /**
+     * Returns {@code true} if this task completed without throwing an
+     * exception and was not cancelled.
+     *
+     * @return {@code true} if this task completed without throwing an
+     * exception and was not cancelled
+     */
+    public final boolean isCompletedNormally() {
+        int s;
+        while ((s = state) == COMPLETING)
+            Thread.yield();
+        return s == NORMAL;
+    }
+
     public boolean cancel(boolean mayInterruptIfRunning) {
         if (!(state == NEW &&
               U.compareAndSwapInt(this, STATE, NEW,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20150304/895f9c0f/attachment.html>


More information about the Concurrency-interest mailing list