Durations in existing JDK APIs

Martin Buchholz martinrb at google.com
Fri Jun 15 17:43:04 UTC 2018


On Wed, May 30, 2018 at 11:32 AM, Doug Lea <dl at cs.oswego.edu> wrote:

>
> The original rationale for designing j.u.c.TimeUnit using the Flyweight
> pattern was to to reduce allocation and GC-related overhead and timing
> jitter for methods that otherwise may operate on the order of
> nanoseconds. But there are many cases in which this is not much of a
> concern (plus JVMs can now sometimes optimize), so people should be
> given a choice. It would be a lot of tedious work (and aggregate code
> bulk) to retrofit every time-related j.u.c method though, and it's not
> clear where to compromise. But at least adding converters should not be
> controversial.
>

Re-reading Doug's assessment, Doug seems reluctant but open to adding at
least some Duration overloads.  Here's  an obvious first candidate in Future
(yes, we have a test that discovers get(Duration) and checks that get(null)
throws UOE instead of NPE.).
(It's a lot of tedious work)

a/util/concurrent/CompletableFuture.java
===================================================================
RCS file:
/export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java,v
retrieving revision 1.212
diff -u -r1.212 CompletableFuture.java
--- src/main/java/util/concurrent/CompletableFuture.java 11 Mar 2018
18:00:05 -0000 1.212
+++ src/main/java/util/concurrent/CompletableFuture.java 15 Jun 2018
17:39:09 -0000
@@ -1983,13 +1983,22 @@
      * while waiting
      * @throws TimeoutException if the wait timed out
      */
-    @SuppressWarnings("unchecked")
     public T get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
-        long nanos = unit.toNanos(timeout);
+        return getNanos(unit.toNanos(timeout));
+    }
+
+    public T get(java.time.Duration timeout)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        return getNanos(TimeUnit.NANOSECONDS.convert(timeout));
+    }
+
+    @SuppressWarnings("unchecked")
+    private T getNanos(long timeoutNanos)
+        throws InterruptedException, ExecutionException, TimeoutException {
         Object r;
         if ((r = result) == null)
-            r = timedGet(nanos);
+            r = timedGet(timeoutNanos);
         return (T) reportGet(r);
     }

@@ -2797,6 +2806,8 @@
             throw new UnsupportedOperationException(); }
         @Override public T get(long timeout, TimeUnit unit) {
             throw new UnsupportedOperationException(); }
+        @Override public T get(java.time.Duration duration) {
+            throw new UnsupportedOperationException(); }
         @Override public T getNow(T valueIfAbsent) {
             throw new UnsupportedOperationException(); }
         @Override public T join() {
Index: src/main/java/util/concurrent/Future.java
===================================================================
RCS file:
/export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/Future.java,v
retrieving revision 1.41
diff -u -r1.41 Future.java
--- src/main/java/util/concurrent/Future.java 8 Oct 2016 18:52:37 -0000 1.41
+++ src/main/java/util/concurrent/Future.java 15 Jun 2018 17:39:09 -0000
@@ -6,6 +6,10 @@

 package java.util.concurrent;

+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.time.Duration;
+
 /**
  * A {@code Future} represents the result of an asynchronous
  * computation.  Methods are provided to check if the computation is
@@ -126,7 +130,30 @@
      * @throws InterruptedException if the current thread was interrupted
      * while waiting
      * @throws TimeoutException if the wait timed out
+     * @throws NullPointerException if {@code unit} is null
      */
     V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException;
+
+    /**
+     * Waits if necessary for at most the given time for the computation
+     * to complete, and then retrieves its result, if available.
+     *
+     * <p>Equivalent to: <pre> {@code
+     * get(NANOSECONDS.convert(timeout), NANOSECONDS)}</pre>
+     *
+     * @param timeout the maximum time to wait
+     * @return the computed result
+     * @throws CancellationException if the computation was cancelled
+     * @throws ExecutionException if the computation threw an
+     * exception
+     * @throws InterruptedException if the current thread was interrupted
+     * while waiting
+     * @throws TimeoutException if the wait timed out
+     * @throws NullPointerException if {@code timeout} is null
+     */
+    default V get(Duration timeout)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        return get(NANOSECONDS.convert(timeout), NANOSECONDS);
+    }
 }


More information about the core-libs-dev mailing list