ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/concurrent/TimeUnit.java
Revision: 1.4
Committed: Wed Feb 4 09:04:24 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +3 -0 lines
Log Message:
add missing @since 1.6

File Contents

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