On Wed, May 30, 2018 at 11:32 AM, Doug Lea <d...@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); + } }