Re: Durations in existing JDK APIs

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Durations in existing JDK APIs

JSR166 Concurrency mailing list


On Wed, May 30, 2018 at 11:32 AM, Doug Lea <[hidden email]> 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);
+    }
 }


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest