ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/TimeUnit.java (file contents):
Revision 1.27 by dl, Tue Mar 8 12:27:11 2005 UTC vs.
Revision 1.50 by dl, Thu Mar 24 11:41:51 2016 UTC

# Line 1 | Line 1
1   /*
2 <  * Written by Doug Lea with assistance from members of JCP JSR-166
3 <  * Expert Group and released to the public domain, as explained at
4 <  * http://creativecommons.org/licenses/publicdomain
5 <  */
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain, as explained at
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5 > */
6  
7   package java.util.concurrent;
8  
9 + import java.time.temporal.ChronoUnit;
10 + import java.util.Objects;
11 +
12   /**
13 < * A <tt>TimeUnit</tt> represents time durations at a given unit of
13 > * A {@code TimeUnit} represents time durations at a given unit of
14   * granularity and provides utility methods to convert across units,
15   * and to perform timing and delay operations in these units.  A
16 < * <tt>TimeUnit</tt> does not maintain time information, but only
16 > * {@code TimeUnit} does not maintain time information, but only
17   * helps organize and use time representations that may be maintained
18   * separately across various contexts.  A nanosecond is defined as one
19   * thousandth of a microsecond, a microsecond as one thousandth of a
# Line 18 | Line 21 | package java.util.concurrent;
21   * as sixty seconds, an hour as sixty minutes, and a day as twenty four
22   * hours.
23   *
24 < * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
24 > * <p>A {@code TimeUnit} is mainly used to inform time-based methods
25   * how a given timing parameter should be interpreted. For example,
26   * the following code will timeout in 50 milliseconds if the {@link
27   * java.util.concurrent.locks.Lock lock} is not available:
28   *
29 < * <pre>  Lock lock = ...;
30 < *  if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
31 < * </pre>
29 > * <pre> {@code
30 > * Lock lock = ...;
31 > * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre>
32 > *
33   * while this code will timeout in 50 seconds:
34 < * <pre>
35 < *  Lock lock = ...;
36 < *  if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
33 < * </pre>
34 > * <pre> {@code
35 > * Lock lock = ...;
36 > * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre>
37   *
38   * Note however, that there is no guarantee that a particular timeout
39   * implementation will be able to notice the passage of time at the
40 < * same granularity as the given <tt>TimeUnit</tt>.
40 > * same granularity as the given {@code TimeUnit}.
41   *
42   * @since 1.5
43   * @author Doug Lea
44   */
45   public enum TimeUnit {
46 <    NANOSECONDS (0) {
47 <        public long toNanos(long d)   { return d; }
48 <        public long toMicros(long d)  { return d/(C1/C0); }
49 <        public long toMillis(long d)  { return d/(C2/C0); }
50 <        public long toSeconds(long d) { return d/(C3/C0); }
51 <        public long toMinutes(long d) { return d/(C4/C0); }
52 <        public long toHours(long d)   { return d/(C5/C0); }
53 <        public long toDays(long d)    { return d/(C6/C0); }
54 <        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
55 <        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
56 <    },
57 <    MICROSECONDS (1) {
58 <        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
59 <        public long toMicros(long d)  { return d; }
60 <        public long toMillis(long d)  { return d/(C2/C1); }
61 <        public long toSeconds(long d) { return d/(C3/C1); }
62 <        public long toMinutes(long d) { return d/(C4/C1); }
63 <        public long toHours(long d)   { return d/(C5/C1); }
64 <        public long toDays(long d)    { return d/(C6/C1); }
65 <        public long convert(long d, TimeUnit u) { return u.toMicros(d); }
66 <        int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
67 <    },
68 <    MILLISECONDS (2) {
69 <        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
70 <        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
71 <        public long toMillis(long d)  { return d; }
72 <        public long toSeconds(long d) { return d/(C3/C2); }
73 <        public long toMinutes(long d) { return d/(C4/C2); }
74 <        public long toHours(long d)   { return d/(C5/C2); }
75 <        public long toDays(long d)    { return d/(C6/C2); }
76 <        public long convert(long d, TimeUnit u) { return u.toMillis(d); }
77 <        int excessNanos(long d, long m) { return 0; }
78 <    },
79 <    SECONDS (3) {
80 <        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
81 <        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
82 <        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
83 <        public long toSeconds(long d) { return d; }
84 <        public long toMinutes(long d) { return d/(C4/C3); }
85 <        public long toHours(long d)   { return d/(C5/C3); }
86 <        public long toDays(long d)    { return d/(C6/C3); }
87 <        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
88 <        int excessNanos(long d, long m) { return 0; }
89 <    },
90 <    MINUTES (4) {
91 <        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
92 <        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
93 <        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
94 <        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
95 <        public long toMinutes(long d) { return d; }
96 <        public long toHours(long d)   { return d/(C5/C4); }
97 <        public long toDays(long d)    { return d/(C6/C4); }
98 <        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
99 <        int excessNanos(long d, long m) { return 0; }
100 <    },
101 <    HOURS (5) {
102 <        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
103 <        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
104 <        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
105 <        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
106 <        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
107 <        public long toHours(long d)   { return d; }
108 <        public long toDays(long d)    { return d/(C6/C5); }
109 <        public long convert(long d, TimeUnit u) { return u.toHours(d); }
110 <        int excessNanos(long d, long m) { return 0; }
111 <    },
112 <    DAYS (6) {
113 <        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
114 <        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
115 <        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
116 <        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
117 <        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
118 <        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
119 <        public long toDays(long d)    { return d; }
120 <        public long convert(long d, TimeUnit u) { return u.toDays(d); }
121 <        int excessNanos(long d, long m) { return 0; }
122 <    };
123 <    
124 <    /**
125 <     * The index of this unit. This value is no longer used in this
126 <     * version of this class, but is retained for serialization
127 <     * compatibility with previous version.
128 <     */
129 <    private final int index;
130 <    
131 <    /** Internal constructor */
132 <    TimeUnit(int index) {
133 <        this.index = index;
134 <    }
135 <    
136 <    // Handy constants for conversion methods
137 <    static final long C0 = 1L;
138 <    static final long C1 = C0 * 1000L;
136 <    static final long C2 = C1 * 1000L;
137 <    static final long C3 = C2 * 1000L;
138 <    static final long C4 = C3 * 60L;
139 <    static final long C5 = C4 * 60L;
140 <    static final long C6 = C5 * 24L;
141 <    
142 <    static final long MAX = Long.MAX_VALUE;
143 <    
144 <    /**
145 <     * Scale d by m, checking for overflow.
146 <     * This has a short name to make above code more readable.
147 <     */
148 <    static long x(long d, long m, long over) {
149 <        if (d >  over) return Long.MAX_VALUE;
150 <        if (d < -over) return Long.MIN_VALUE;
151 <        return d * m;
152 <    }
153 <    
154 <    /**
155 <     * Convert the given time duration in the given unit to this
156 <     * unit.  Conversions from finer to coarser granularities
157 <     * truncate, so lose precision. For example converting
158 <     * <tt>999</tt> milliseconds to seconds results in
159 <     * <tt>0</tt>. Conversions from coarser to finer granularities
160 <     * with arguments that would numerically overflow saturate to
161 <     * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
162 <     * if positive.
46 >    /**
47 >     * Time unit representing one thousandth of a microsecond.
48 >     */
49 >    NANOSECONDS(1L), // (cannot use symbolic scale names here)
50 >    /**
51 >     * Time unit representing one thousandth of a millisecond.
52 >     */
53 >    MICROSECONDS(1000L),
54 >    /**
55 >     * Time unit representing one thousandth of a second.
56 >     */
57 >    MILLISECONDS(1000L * 1000L),
58 >    /**
59 >     * Time unit representing one second.
60 >     */
61 >    SECONDS(1000L * 1000L * 1000L),
62 >    /**
63 >     * Time unit representing sixty seconds.
64 >     * @since 1.6
65 >     */
66 >    MINUTES(1000L * 1000L * 1000L * 60L),
67 >    /**
68 >     * Time unit representing sixty minutes.
69 >     * @since 1.6
70 >     */
71 >    HOURS(1000L * 1000L * 1000L * 60L * 60L),
72 >    /**
73 >     * Time unit representing twenty four hours.
74 >     * @since 1.6
75 >     */
76 >    DAYS(1000L * 1000L * 1000L * 60L * 60L * 24L);
77 >
78 >    // Scales as constants
79 >    private static final long NANO_SCALE   = 1L;
80 >    private static final long MICRO_SCALE  = 1000L * NANO_SCALE;
81 >    private static final long MILLI_SCALE  = 1000L * MICRO_SCALE;
82 >    private static final long SECOND_SCALE = 1000L * MILLI_SCALE;
83 >    private static final long MINUTE_SCALE = 60L * SECOND_SCALE;
84 >    private static final long HOUR_SCALE   = 60L * MINUTE_SCALE;
85 >    private static final long DAY_SCALE    = 24L * HOUR_SCALE;
86 >
87 >    /*
88 >     * Instances cache conversion ratios and saturation cutoffs for
89 >     * the two units commonly used for JDK timing, used in methods
90 >     * toNanos and toMillis. Other cases compute them, in method cvt.
91 >     */
92 >
93 >    private final long scale;
94 >    private final long maxNanos;
95 >    private final long millisRatio;
96 >    private final long maxMillis;
97 >
98 >    TimeUnit(long scale) {
99 >        this.scale = scale;
100 >        this.maxNanos = Long.MAX_VALUE / scale;
101 >        long r = (scale >= MILLI_SCALE ? scale / MILLI_SCALE :
102 >                  MILLI_SCALE / scale);
103 >        this.millisRatio = r;
104 >        this.maxMillis = Long.MAX_VALUE / r;
105 >    }
106 >
107 >    /**
108 >     * General conversion utility.
109 >     *
110 >     * @param d duration
111 >     * @param dst result scale unit
112 >     * @param src source scale unit
113 >     */
114 >    private static long cvt(long d, long dst, long src) {
115 >        long r, m;
116 >        if (src == dst)
117 >            return d;
118 >        else if (src < dst)
119 >            return d / (dst / src);
120 >        else if (d > (m = Long.MAX_VALUE / (r = src / dst)))
121 >            return Long.MAX_VALUE;
122 >        else if (d < -m)
123 >            return Long.MIN_VALUE;
124 >        else
125 >            return d * r;
126 >    }
127 >
128 >    /**
129 >     * Converts the given time duration in the given unit to this unit.
130 >     * Conversions from finer to coarser granularities truncate, so
131 >     * lose precision. For example, converting {@code 999} milliseconds
132 >     * to seconds results in {@code 0}. Conversions from coarser to
133 >     * finer granularities with arguments that would numerically
134 >     * overflow saturate to {@code Long.MIN_VALUE} if negative or
135 >     * {@code Long.MAX_VALUE} if positive.
136 >     *
137 >     * <p>For example, to convert 10 minutes to milliseconds, use:
138 >     * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)}
139       *
140 <     * @param duration the time duration in the given <tt>unit</tt>
141 <     * @param unit the unit of the <tt>duration</tt> argument
140 >     * @param sourceDuration the time duration in the given {@code sourceUnit}
141 >     * @param sourceUnit the unit of the {@code sourceDuration} argument
142       * @return the converted duration in this unit,
143 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
144 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
143 >     * or {@code Long.MIN_VALUE} if conversion would negatively
144 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
145       */
146 <    public abstract long convert(long duration, TimeUnit unit);
147 <    
146 >    public long convert(long sourceDuration, TimeUnit sourceUnit) {
147 >        return cvt(sourceDuration, scale, sourceUnit.scale);
148 >    }
149 >
150      /**
151 <     * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
151 >     * Equivalent to
152 >     * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
153       * @param duration the duration
154       * @return the converted duration,
155 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
156 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
178 <     * @see #convert
155 >     * or {@code Long.MIN_VALUE} if conversion would negatively
156 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
157       */
158 <    public abstract long toNanos(long duration);
159 <    
158 >    public long toNanos(long duration) {
159 >        long s, m;
160 >        if ((s = scale) == NANO_SCALE)
161 >            return duration;
162 >        else if (duration > (m = maxNanos))
163 >            return Long.MAX_VALUE;
164 >        else if (duration < -m)
165 >            return Long.MIN_VALUE;
166 >        else
167 >            return duration * s;
168 >    }
169 >
170      /**
171 <     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
171 >     * Equivalent to
172 >     * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
173       * @param duration the duration
174       * @return the converted duration,
175 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
176 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
188 <     * @see #convert
175 >     * or {@code Long.MIN_VALUE} if conversion would negatively
176 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
177       */
178 <    public abstract long toMicros(long duration);
179 <    
178 >    public long toMicros(long duration) {
179 >        return cvt(duration, MICRO_SCALE, scale);
180 >    }
181 >
182      /**
183 <     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
183 >     * Equivalent to
184 >     * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
185       * @param duration the duration
186       * @return the converted duration,
187 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
188 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
198 <     * @see #convert
187 >     * or {@code Long.MIN_VALUE} if conversion would negatively
188 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
189       */
190 <    public abstract long toMillis(long duration);
191 <    
190 >    public long toMillis(long duration) {
191 >        long s, m;
192 >        if ((s = scale) == MILLI_SCALE)
193 >            return duration;
194 >        else if (s < MILLI_SCALE)
195 >            return duration / millisRatio;
196 >        else if (duration > (m = maxMillis))
197 >            return Long.MAX_VALUE;
198 >        else if (duration < -m)
199 >            return Long.MIN_VALUE;
200 >        else
201 >            return duration * millisRatio;
202 >    }
203 >
204      /**
205 <     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
205 >     * Equivalent to
206 >     * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}.
207       * @param duration the duration
208       * @return the converted duration,
209 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
210 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
208 <     * @see #convert
209 >     * or {@code Long.MIN_VALUE} if conversion would negatively
210 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
211       */
212 <    public abstract long toSeconds(long duration);
213 <    
212 >    public long toSeconds(long duration) {
213 >        return cvt(duration, SECOND_SCALE, scale);
214 >    }
215 >
216      /**
217 <     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
217 >     * Equivalent to
218 >     * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
219       * @param duration the duration
220       * @return the converted duration,
221 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
222 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
223 <     * @see #convert
221 >     * or {@code Long.MIN_VALUE} if conversion would negatively
222 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
223 >     * @since 1.6
224       */
225 <    public abstract long toMinutes(long duration);
226 <    
225 >    public long toMinutes(long duration) {
226 >        return cvt(duration, MINUTE_SCALE, scale);
227 >    }
228 >
229      /**
230 <     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
230 >     * Equivalent to
231 >     * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
232       * @param duration the duration
233       * @return the converted duration,
234 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
235 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
236 <     * @see #convert
234 >     * or {@code Long.MIN_VALUE} if conversion would negatively
235 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
236 >     * @since 1.6
237       */
238 <    public abstract long toHours(long duration);
239 <    
238 >    public long toHours(long duration) {
239 >        return cvt(duration, HOUR_SCALE, scale);
240 >    }
241 >
242      /**
243 <     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
243 >     * Equivalent to
244 >     * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}.
245       * @param duration the duration
246       * @return the converted duration
247 <     * @see #convert
247 >     * @since 1.6
248       */
249 <    public abstract long toDays(long duration);
250 <    
249 >    public long toDays(long duration) {
250 >        return cvt(duration, DAY_SCALE, scale);
251 >    }
252 >
253      /**
254       * Utility to compute the excess-nanosecond argument to wait,
255       * sleep, join.
# Line 244 | Line 257 | public enum TimeUnit {
257       * @param m the number of milliseconds
258       * @return the number of nanoseconds
259       */
260 <    abstract int excessNanos(long d, long m);
261 <    
260 >    private int excessNanos(long d, long m) {
261 >        long s;
262 >        if ((s = scale) == NANO_SCALE)
263 >            return (int)(d - (m * MILLI_SCALE));
264 >        else if (s == MICRO_SCALE)
265 >            return (int)((d * 1000L) - (m * MILLI_SCALE));
266 >        else
267 >            return 0;
268 >    }
269 >
270      /**
271 <     * Perform a timed <tt>Object.wait</tt> using this time unit.
271 >     * Performs a timed {@link Object#wait(long, int) Object.wait}
272 >     * using this time unit.
273       * This is a convenience method that converts timeout arguments
274 <     * into the form required by the <tt>Object.wait</tt> method.
274 >     * into the form required by the {@code Object.wait} method.
275       *
276 <     * <p>For example, you could implement a blocking <tt>poll</tt>
276 >     * <p>For example, you could implement a blocking {@code poll}
277       * method (see {@link BlockingQueue#poll BlockingQueue.poll})
278       * using:
279       *
280 <     * <pre>  public synchronized  Object poll(long timeout, TimeUnit unit) throws InterruptedException {
281 <     *    while (empty) {
282 <     *      unit.timedWait(this, timeout);
283 <     *      ...
284 <     *    }
285 <     *  }</pre>
280 >     * <pre> {@code
281 >     * public synchronized Object poll(long timeout, TimeUnit unit)
282 >     *     throws InterruptedException {
283 >     *   while (empty) {
284 >     *     unit.timedWait(this, timeout);
285 >     *     ...
286 >     *   }
287 >     * }}</pre>
288       *
289       * @param obj the object to wait on
290 <     * @param timeout the maximum time to wait.
291 <     * @throws InterruptedException if interrupted while waiting.
292 <     * @see Object#wait(long, int)
290 >     * @param timeout the maximum time to wait. If less than
291 >     * or equal to zero, do not wait at all.
292 >     * @throws InterruptedException if interrupted while waiting
293       */
294      public void timedWait(Object obj, long timeout)
295 <    throws InterruptedException {
295 >            throws InterruptedException {
296          if (timeout > 0) {
297              long ms = toMillis(timeout);
298              int ns = excessNanos(timeout, ms);
299              obj.wait(ms, ns);
300          }
301      }
302 <    
302 >
303      /**
304 <     * Perform a timed <tt>Thread.join</tt> using this time unit.
304 >     * Performs a timed {@link Thread#join(long, int) Thread.join}
305 >     * using this time unit.
306       * This is a convenience method that converts time arguments into the
307 <     * form required by the <tt>Thread.join</tt> method.
307 >     * form required by the {@code Thread.join} method.
308 >     *
309       * @param thread the thread to wait for
310 <     * @param timeout the maximum time to wait
311 <     * @throws InterruptedException if interrupted while waiting.
312 <     * @see Thread#join(long, int)
310 >     * @param timeout the maximum time to wait. If less than
311 >     * or equal to zero, do not wait at all.
312 >     * @throws InterruptedException if interrupted while waiting
313       */
314      public void timedJoin(Thread thread, long timeout)
315 <    throws InterruptedException {
315 >            throws InterruptedException {
316          if (timeout > 0) {
317              long ms = toMillis(timeout);
318              int ns = excessNanos(timeout, ms);
319              thread.join(ms, ns);
320          }
321      }
322 <    
322 >
323      /**
324 <     * Perform a <tt>Thread.sleep</tt> using this unit.
324 >     * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
325 >     * this time unit.
326       * This is a convenience method that converts time arguments into the
327 <     * form required by the <tt>Thread.sleep</tt> method.
328 <     * @param timeout the minimum time to sleep
329 <     * @throws InterruptedException if interrupted while sleeping.
330 <     * @see Thread#sleep
327 >     * form required by the {@code Thread.sleep} method.
328 >     *
329 >     * @param timeout the minimum time to sleep. If less than
330 >     * or equal to zero, do not sleep at all.
331 >     * @throws InterruptedException if interrupted while sleeping
332       */
333      public void sleep(long timeout) throws InterruptedException {
334          if (timeout > 0) {
# Line 309 | Line 337 | public enum TimeUnit {
337              Thread.sleep(ms, ns);
338          }
339      }
340 <    
340 >
341 >    /**
342 >     * Converts this {@code TimeUnit} to the equivalent {@code ChronoUnit}.
343 >     *
344 >     * @return the converted equivalent ChronoUnit
345 >     * @since 9
346 >     */
347 >    public ChronoUnit toChronoUnit() {
348 >        switch (this) {
349 >        case NANOSECONDS:  return ChronoUnit.NANOS;
350 >        case MICROSECONDS: return ChronoUnit.MICROS;
351 >        case MILLISECONDS: return ChronoUnit.MILLIS;
352 >        case SECONDS:      return ChronoUnit.SECONDS;
353 >        case MINUTES:      return ChronoUnit.MINUTES;
354 >        case HOURS:        return ChronoUnit.HOURS;
355 >        case DAYS:         return ChronoUnit.DAYS;
356 >        default: throw new AssertionError();
357 >        }
358 >    }
359 >
360 >    /**
361 >     * Converts a {@code ChronoUnit} to the equivalent {@code TimeUnit}.
362 >     *
363 >     * @param chronoUnit the ChronoUnit to convert
364 >     * @return the converted equivalent TimeUnit
365 >     * @throws IllegalArgumentException if {@code chronoUnit} has no
366 >     *         equivalent TimeUnit
367 >     * @throws NullPointerException if {@code chronoUnit} is null
368 >     * @since 9
369 >     */
370 >    public static TimeUnit of(ChronoUnit chronoUnit) {
371 >        switch (Objects.requireNonNull(chronoUnit, "chronoUnit")) {
372 >        case NANOS:   return TimeUnit.NANOSECONDS;
373 >        case MICROS:  return TimeUnit.MICROSECONDS;
374 >        case MILLIS:  return TimeUnit.MILLISECONDS;
375 >        case SECONDS: return TimeUnit.SECONDS;
376 >        case MINUTES: return TimeUnit.MINUTES;
377 >        case HOURS:   return TimeUnit.HOURS;
378 >        case DAYS:    return TimeUnit.DAYS;
379 >        default:
380 >            throw new IllegalArgumentException(
381 >                "No TimeUnit equivalent for " + chronoUnit);
382 >        }
383 >    }
384 >
385   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines