Without commenting on the proposed implementation below, Future seems like a good place to start. I suspect that ExecutorService and ScheduledExecutorService would also be good targets to enhance. Stephen
On Fri, 15 Jun 2018, 18:43 Martin Buchholz, <marti...@google.com> wrote: > > > 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); > + } > } > >