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.55 by jsr166, Sat Mar 26 16:18:25 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)); }
115 <        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
116 <        public long toDays(long d)    { return d; }
117 <        public long convert(long d, TimeUnit u) { return u.toDays(d); }
118 <        int excessNanos(long d, long m) { return 0; }
119 <    };
120 <    
121 <    /**
122 <     * The index of this unit. This value is no longer used in this
123 <     * version of this class, but is retained for serialization
124 <     * compatibility with previous version.
125 <     */
126 <    private final int index;
127 <    
128 <    /** Internal constructor */
129 <    TimeUnit(int index) {
130 <        this.index = index;
131 <    }
132 <    
133 <    // Handy constants for conversion methods
134 <    static final long C0 = 1L;
135 <    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 units up through SECONDS. Other cases compute them, in
90 >     * method cvt.
91 >     */
92 >
93 >    private final long scale;
94 >    private final long maxNanos;
95 >    private final long maxMicros;
96 >    private final long maxMillis;
97 >    private final long maxSecs;
98 >    private final long microRatio;
99 >    private final int milliRatio;   // fits in 32 bits
100 >    private final int secRatio;     // fits in 32 bits
101 >
102 >    TimeUnit(long s) {
103 >        this.scale = s;
104 >        this.maxNanos = Long.MAX_VALUE / s;
105 >        long ur = (s >= MICRO_SCALE) ? (s / MICRO_SCALE) : (MICRO_SCALE / s);
106 >        this.microRatio = ur;
107 >        this.maxMicros = Long.MAX_VALUE / ur;
108 >        long mr = (s >= MILLI_SCALE) ? (s / MILLI_SCALE) : (MILLI_SCALE / s);
109 >        this.milliRatio = (int)mr;
110 >        this.maxMillis = Long.MAX_VALUE / mr;
111 >        long sr = (s >= SECOND_SCALE) ? (s / SECOND_SCALE) : (SECOND_SCALE / s);
112 >        this.secRatio = (int)sr;
113 >        this.maxSecs = Long.MAX_VALUE / sr;
114 >    }
115 >
116 >    /**
117 >     * General conversion utility.
118       *
119 <     * @param duration the time duration in the given <tt>unit</tt>
120 <     * @param unit the unit of the <tt>duration</tt> argument
119 >     * @param d duration
120 >     * @param dst result scale unit
121 >     * @param src source scale unit
122 >     */
123 >    private static long cvt(long d, long dst, long src) {
124 >        long r, m;
125 >        if (src == dst)
126 >            return d;
127 >        else if (src < dst)
128 >            return d / (dst / src);
129 >        else if (d > (m = Long.MAX_VALUE / (r = src / dst)))
130 >            return Long.MAX_VALUE;
131 >        else if (d < -m)
132 >            return Long.MIN_VALUE;
133 >        else
134 >            return d * r;
135 >    }
136 >
137 >    /**
138 >     * Converts the given time duration in the given unit to this unit.
139 >     * Conversions from finer to coarser granularities truncate, so
140 >     * lose precision. For example, converting {@code 999} milliseconds
141 >     * to seconds results in {@code 0}. Conversions from coarser to
142 >     * finer granularities with arguments that would numerically
143 >     * overflow saturate to {@code Long.MIN_VALUE} if negative or
144 >     * {@code Long.MAX_VALUE} if positive.
145 >     *
146 >     * <p>For example, to convert 10 minutes to milliseconds, use:
147 >     * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)}
148 >     *
149 >     * @param sourceDuration the time duration in the given {@code sourceUnit}
150 >     * @param sourceUnit the unit of the {@code sourceDuration} argument
151       * @return the converted duration in this unit,
152 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
153 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
152 >     * or {@code Long.MIN_VALUE} if conversion would negatively
153 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
154       */
155 <    public abstract long convert(long duration, TimeUnit unit);
156 <    
155 >    public long convert(long sourceDuration, TimeUnit sourceUnit) {
156 >        switch (this) {
157 >        case NANOSECONDS:  return sourceUnit.toNanos(sourceDuration);
158 >        case MICROSECONDS: return sourceUnit.toMicros(sourceDuration);
159 >        case MILLISECONDS: return sourceUnit.toMillis(sourceDuration);
160 >        case SECONDS:      return sourceUnit.toSeconds(sourceDuration);
161 >        default: return cvt(sourceDuration, scale, sourceUnit.scale);
162 >        }
163 >    }
164 >
165      /**
166 <     * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
166 >     * Equivalent to
167 >     * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
168       * @param duration the duration
169       * @return the converted duration,
170 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
171 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
178 <     * @see #convert
170 >     * or {@code Long.MIN_VALUE} if conversion would negatively
171 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
172       */
173 <    public abstract long toNanos(long duration);
174 <    
173 >    public long toNanos(long duration) {
174 >        long s, m;
175 >        if ((s = scale) == NANO_SCALE)
176 >            return duration;
177 >        else if (duration > (m = maxNanos))
178 >            return Long.MAX_VALUE;
179 >        else if (duration < -m)
180 >            return Long.MIN_VALUE;
181 >        else
182 >            return duration * s;
183 >    }
184 >
185      /**
186 <     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
186 >     * Equivalent to
187 >     * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
188       * @param duration the duration
189       * @return the converted duration,
190 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
191 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
188 <     * @see #convert
190 >     * or {@code Long.MIN_VALUE} if conversion would negatively
191 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
192       */
193 <    public abstract long toMicros(long duration);
194 <    
193 >    public long toMicros(long duration) {
194 >        long s, m;
195 >        if ((s = scale) == MICRO_SCALE)
196 >            return duration;
197 >        else if (s < MICRO_SCALE)
198 >            return duration / microRatio;
199 >        else if (duration > (m = maxMicros))
200 >            return Long.MAX_VALUE;
201 >        else if (duration < -m)
202 >            return Long.MIN_VALUE;
203 >        else
204 >            return duration * microRatio;
205 >    }
206 >
207      /**
208 <     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
208 >     * Equivalent to
209 >     * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
210       * @param duration the duration
211       * @return the converted duration,
212 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
213 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
198 <     * @see #convert
212 >     * or {@code Long.MIN_VALUE} if conversion would negatively
213 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
214       */
215 <    public abstract long toMillis(long duration);
216 <    
215 >    public long toMillis(long duration) {
216 >        long s, m;
217 >        if ((s = scale) == MILLI_SCALE)
218 >            return duration;
219 >        else if (s < MILLI_SCALE)
220 >            return duration / milliRatio;
221 >        else if (duration > (m = maxMillis))
222 >            return Long.MAX_VALUE;
223 >        else if (duration < -m)
224 >            return Long.MIN_VALUE;
225 >        else
226 >            return duration * milliRatio;
227 >    }
228 >
229      /**
230 <     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
230 >     * Equivalent to
231 >     * {@link #convert(long, TimeUnit) SECONDS.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.
208 <     * @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       */
237 <    public abstract long toSeconds(long duration);
238 <    
237 >    public long toSeconds(long duration) {
238 >        long s, m;
239 >        if ((s = scale) == SECOND_SCALE)
240 >            return duration;
241 >        else if (s < SECOND_SCALE)
242 >            return duration / secRatio;
243 >        else if (duration > (m = maxSecs))
244 >            return Long.MAX_VALUE;
245 >        else if (duration < -m)
246 >            return Long.MIN_VALUE;
247 >        else
248 >            return duration * secRatio;
249 >    }
250 >
251      /**
252 <     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
252 >     * Equivalent to
253 >     * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
254       * @param duration the duration
255       * @return the converted duration,
256 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
257 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
258 <     * @see #convert
256 >     * or {@code Long.MIN_VALUE} if conversion would negatively
257 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
258 >     * @since 1.6
259       */
260 <    public abstract long toMinutes(long duration);
261 <    
260 >    public long toMinutes(long duration) {
261 >        return cvt(duration, MINUTE_SCALE, scale);
262 >    }
263 >
264      /**
265 <     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
265 >     * Equivalent to
266 >     * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
267       * @param duration the duration
268       * @return the converted duration,
269 <     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
270 <     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
271 <     * @see #convert
269 >     * or {@code Long.MIN_VALUE} if conversion would negatively
270 >     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
271 >     * @since 1.6
272       */
273 <    public abstract long toHours(long duration);
274 <    
273 >    public long toHours(long duration) {
274 >        return cvt(duration, HOUR_SCALE, scale);
275 >    }
276 >
277      /**
278 <     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
278 >     * Equivalent to
279 >     * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}.
280       * @param duration the duration
281       * @return the converted duration
282 <     * @see #convert
282 >     * @since 1.6
283       */
284 <    public abstract long toDays(long duration);
285 <    
284 >    public long toDays(long duration) {
285 >        return cvt(duration, DAY_SCALE, scale);
286 >    }
287 >
288      /**
289       * Utility to compute the excess-nanosecond argument to wait,
290       * sleep, join.
# Line 244 | Line 292 | public enum TimeUnit {
292       * @param m the number of milliseconds
293       * @return the number of nanoseconds
294       */
295 <    abstract int excessNanos(long d, long m);
296 <    
295 >    private int excessNanos(long d, long m) {
296 >        long s;
297 >        if ((s = scale) == NANO_SCALE)
298 >            return (int)(d - (m * MILLI_SCALE));
299 >        else if (s == MICRO_SCALE)
300 >            return (int)((d * 1000L) - (m * MILLI_SCALE));
301 >        else
302 >            return 0;
303 >    }
304 >
305      /**
306 <     * Perform a timed <tt>Object.wait</tt> using this time unit.
306 >     * Performs a timed {@link Object#wait(long, int) Object.wait}
307 >     * using this time unit.
308       * This is a convenience method that converts timeout arguments
309 <     * into the form required by the <tt>Object.wait</tt> method.
309 >     * into the form required by the {@code Object.wait} method.
310       *
311 <     * <p>For example, you could implement a blocking <tt>poll</tt>
311 >     * <p>For example, you could implement a blocking {@code poll}
312       * method (see {@link BlockingQueue#poll BlockingQueue.poll})
313       * using:
314       *
315 <     * <pre>  public synchronized  Object poll(long timeout, TimeUnit unit) throws InterruptedException {
316 <     *    while (empty) {
317 <     *      unit.timedWait(this, timeout);
318 <     *      ...
319 <     *    }
320 <     *  }</pre>
315 >     * <pre> {@code
316 >     * public synchronized Object poll(long timeout, TimeUnit unit)
317 >     *     throws InterruptedException {
318 >     *   while (empty) {
319 >     *     unit.timedWait(this, timeout);
320 >     *     ...
321 >     *   }
322 >     * }}</pre>
323       *
324       * @param obj the object to wait on
325 <     * @param timeout the maximum time to wait.
326 <     * @throws InterruptedException if interrupted while waiting.
327 <     * @see Object#wait(long, int)
325 >     * @param timeout the maximum time to wait. If less than
326 >     * or equal to zero, do not wait at all.
327 >     * @throws InterruptedException if interrupted while waiting
328       */
329      public void timedWait(Object obj, long timeout)
330 <    throws InterruptedException {
330 >            throws InterruptedException {
331          if (timeout > 0) {
332              long ms = toMillis(timeout);
333              int ns = excessNanos(timeout, ms);
334              obj.wait(ms, ns);
335          }
336      }
337 <    
337 >
338      /**
339 <     * Perform a timed <tt>Thread.join</tt> using this time unit.
339 >     * Performs a timed {@link Thread#join(long, int) Thread.join}
340 >     * using this time unit.
341       * This is a convenience method that converts time arguments into the
342 <     * form required by the <tt>Thread.join</tt> method.
342 >     * form required by the {@code Thread.join} method.
343 >     *
344       * @param thread the thread to wait for
345 <     * @param timeout the maximum time to wait
346 <     * @throws InterruptedException if interrupted while waiting.
347 <     * @see Thread#join(long, int)
345 >     * @param timeout the maximum time to wait. If less than
346 >     * or equal to zero, do not wait at all.
347 >     * @throws InterruptedException if interrupted while waiting
348       */
349      public void timedJoin(Thread thread, long timeout)
350 <    throws InterruptedException {
350 >            throws InterruptedException {
351          if (timeout > 0) {
352              long ms = toMillis(timeout);
353              int ns = excessNanos(timeout, ms);
354              thread.join(ms, ns);
355          }
356      }
357 <    
357 >
358      /**
359 <     * Perform a <tt>Thread.sleep</tt> using this unit.
359 >     * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
360 >     * this time unit.
361       * This is a convenience method that converts time arguments into the
362 <     * form required by the <tt>Thread.sleep</tt> method.
363 <     * @param timeout the minimum time to sleep
364 <     * @throws InterruptedException if interrupted while sleeping.
365 <     * @see Thread#sleep
362 >     * form required by the {@code Thread.sleep} method.
363 >     *
364 >     * @param timeout the minimum time to sleep. If less than
365 >     * or equal to zero, do not sleep at all.
366 >     * @throws InterruptedException if interrupted while sleeping
367       */
368      public void sleep(long timeout) throws InterruptedException {
369          if (timeout > 0) {
# Line 309 | Line 372 | public enum TimeUnit {
372              Thread.sleep(ms, ns);
373          }
374      }
375 <    
375 >
376 >    /**
377 >     * Converts this {@code TimeUnit} to the equivalent {@code ChronoUnit}.
378 >     *
379 >     * @return the converted equivalent ChronoUnit
380 >     * @since 9
381 >     */
382 >    public ChronoUnit toChronoUnit() {
383 >        switch (this) {
384 >        case NANOSECONDS:  return ChronoUnit.NANOS;
385 >        case MICROSECONDS: return ChronoUnit.MICROS;
386 >        case MILLISECONDS: return ChronoUnit.MILLIS;
387 >        case SECONDS:      return ChronoUnit.SECONDS;
388 >        case MINUTES:      return ChronoUnit.MINUTES;
389 >        case HOURS:        return ChronoUnit.HOURS;
390 >        case DAYS:         return ChronoUnit.DAYS;
391 >        default: throw new AssertionError();
392 >        }
393 >    }
394 >
395 >    /**
396 >     * Converts a {@code ChronoUnit} to the equivalent {@code TimeUnit}.
397 >     *
398 >     * @param chronoUnit the ChronoUnit to convert
399 >     * @return the converted equivalent TimeUnit
400 >     * @throws IllegalArgumentException if {@code chronoUnit} has no
401 >     *         equivalent TimeUnit
402 >     * @throws NullPointerException if {@code chronoUnit} is null
403 >     * @since 9
404 >     */
405 >    public static TimeUnit of(ChronoUnit chronoUnit) {
406 >        switch (Objects.requireNonNull(chronoUnit, "chronoUnit")) {
407 >        case NANOS:   return TimeUnit.NANOSECONDS;
408 >        case MICROS:  return TimeUnit.MICROSECONDS;
409 >        case MILLIS:  return TimeUnit.MILLISECONDS;
410 >        case SECONDS: return TimeUnit.SECONDS;
411 >        case MINUTES: return TimeUnit.MINUTES;
412 >        case HOURS:   return TimeUnit.HOURS;
413 >        case DAYS:    return TimeUnit.DAYS;
414 >        default:
415 >            throw new IllegalArgumentException(
416 >                "No TimeUnit equivalent for " + chronoUnit);
417 >        }
418 >    }
419 >
420   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines