1 /*
2 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.3 *4 *5 *6 *7 *8 *9 *10 *11 *12 *13 *14 *15 *16 *17 *18 *19 *20 *21 *22 *23 */
24
25 /*
26 *27 *28 *29 *30 *31 * Written by Doug Lea with assistance from members of JCP JSR-16632 * Expert Group and released to the public domain, as explained at33 *http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 packagejava.util.concurrent;37
38 /**
39 * A {@codeTimeUnit} represents time durations at a given unit of40 * granularity and provides utility methods to convert across units,41 * and to perform timing and delay operations in these units. A42 * {@codeTimeUnit} does not maintain time information, but only43 * helps organize and use time representations that may be maintained44 * separately across various contexts. A nanosecond is defined as one45 * thousandth of a microsecond, a microsecond as one thousandth of a46 * millisecond, a millisecond as one thousandth of a second, a minute47 * as sixty seconds, an hour as sixty minutes, and a day as twenty four48 * hours.49 *50 *
A {@codeTimeUnit} is mainly used to inform time-based methods51 * how a given timing parameter should be interpreted. For example,52 * the following code will timeout in 50 milliseconds if the {@link
53 * java.util.concurrent.locks.Lock lock} is not available:54 *55 *
{@code
56 * Lock lock = ...;57 * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}
58 *59 * while this code will timeout in 50 seconds:60 *{@code
61 * Lock lock = ...;62 * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}
63 *64 * Note however, that there is no guarantee that a particular timeout65 * implementation will be able to notice the passage of time at the66 * same granularity as the given {@codeTimeUnit}.67 *68 *@since1.569 *@authorDoug Lea70 */71 public enumTimeUnit {72 /**
73 * Time unit representing one thousandth of a microsecond74 */
75 NANOSECONDS {76 public long toNanos(long d) { returnd; }77 public long toMicros(long d) { return d/(C1/C0); }78 public long toMillis(long d) { return d/(C2/C0); }79 public long toSeconds(long d) { return d/(C3/C0); }80 public long toMinutes(long d) { return d/(C4/C0); }81 public long toHours(long d) { return d/(C5/C0); }82 public long toDays(long d) { return d/(C6/C0); }83 public long convert(long d, TimeUnit u) { returnu.toNanos(d); }84 int excessNanos(long d, long m) { return (int)(d - (m*C2)); }85 },86
87 /**
88 * Time unit representing one thousandth of a millisecond89 */
90 MICROSECONDS {91 public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }92 public long toMicros(long d) { returnd; }93 public long toMillis(long d) { return d/(C2/C1); }94 public long toSeconds(long d) { return d/(C3/C1); }95 public long toMinutes(long d) { return d/(C4/C1); }96 public long toHours(long d) { return d/(C5/C1); }97 public long toDays(long d) { return d/(C6/C1); }98 public long convert(long d, TimeUnit u) { returnu.toMicros(d); }99 int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }100 },101
102 /**
103 * Time unit representing one thousandth of a second104 */
105 MILLISECONDS {106 public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }107 public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }108 public long toMillis(long d) { returnd; }109 public long toSeconds(long d) { return d/(C3/C2); }110 public long toMinutes(long d) { return d/(C4/C2); }111 public long toHours(long d) { return d/(C5/C2); }112 public long toDays(long d) { return d/(C6/C2); }113 public long convert(long d, TimeUnit u) { returnu.toMillis(d); }114 int excessNanos(long d, long m) { return 0; }115 },116
117 /**
118 * Time unit representing one second119 */
120 SECONDS {121 public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }122 public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }123 public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }124 public long toSeconds(long d) { returnd; }125 public long toMinutes(long d) { return d/(C4/C3); }126 public long toHours(long d) { return d/(C5/C3); }127 public long toDays(long d) { return d/(C6/C3); }128 public long convert(long d, TimeUnit u) { returnu.toSeconds(d); }129 int excessNanos(long d, long m) { return 0; }130 },131
132 /**
133 * Time unit representing sixty seconds134 */
135 MINUTES {136 public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }137 public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }138 public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }139 public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }140 public long toMinutes(long d) { returnd; }141 public long toHours(long d) { return d/(C5/C4); }142 public long toDays(long d) { return d/(C6/C4); }143 public long convert(long d, TimeUnit u) { returnu.toMinutes(d); }144 int excessNanos(long d, long m) { return 0; }145 },146
147 /**
148 * Time unit representing sixty minutes149 */
150 HOURS {151 public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }152 public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }153 public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }154 public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }155 public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }156 public long toHours(long d) { returnd; }157 public long toDays(long d) { return d/(C6/C5); }158 public long convert(long d, TimeUnit u) { returnu.toHours(d); }159 int excessNanos(long d, long m) { return 0; }160 },161
162 /**
163 * Time unit representing twenty four hours164 */
165 DAYS {166 public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }167 public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }168 public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }169 public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }170 public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }171 public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }172 public long toDays(long d) { returnd; }173 public long convert(long d, TimeUnit u) { returnu.toDays(d); }174 int excessNanos(long d, long m) { return 0; }175 };176
177 //Handy constants for conversion methods
178 static final long C0 = 1L;179 static final long C1 = C0 * 1000L;180 static final long C2 = C1 * 1000L;181 static final long C3 = C2 * 1000L;182 static final long C4 = C3 * 60L;183 static final long C5 = C4 * 60L;184 static final long C6 = C5 * 24L;185
186 static final long MAX =Long.MAX_VALUE;187
188 /**
189 * Scale d by m, checking for overflow.190 * This has a short name to make above code more readable.191 */
192 static long x(long d, long m, longover) {193 if (d > over) returnLong.MAX_VALUE;194 if (d < -over) returnLong.MIN_VALUE;195 return d *m;196 }197
198 //To maintain full signature compatibility with 1.5, and to improve the199 //clarity of the generated javadoc (see 6287639: Abstract methods in200 //enum classes should not be listed as abstract), method convert201 //etc. are not declared abstract but otherwise act as abstract methods.
202
203 /**
204 * Converts the given time duration in the given unit to this unit.205 * Conversions from finer to coarser granularities truncate, so206 * lose precision. For example, converting {@code999} milliseconds207 * to seconds results in {@code0}. Conversions from coarser to208 * finer granularities with arguments that would numerically209 * overflow saturate to {@codeLong.MIN_VALUE} if negative or210 * {@codeLong.MAX_VALUE} if positive.211 *212 *
For example, to convert 10 minutes to milliseconds, use:213 * {@codeTimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)}214 *215 *@paramsourceDuration the time duration in the given {@codesourceUnit}216 *@paramsourceUnit the unit of the {@codesourceDuration} argument217 *@returnthe converted duration in this unit,218 * or {@codeLong.MIN_VALUE} if conversion would negatively219 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.220 */
221 public long convert(longsourceDuration, TimeUnit sourceUnit) {222 throw newAbstractMethodError();223 }224
225 /**
226 * Equivalent to227 * {@link#convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.228 *@paramduration the duration229 *@returnthe converted duration,230 * or {@codeLong.MIN_VALUE} if conversion would negatively231 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.232 */
233 public long toNanos(longduration) {234 throw newAbstractMethodError();235 }236
237 /**
238 * Equivalent to239 * {@link#convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.240 *@paramduration the duration241 *@returnthe converted duration,242 * or {@codeLong.MIN_VALUE} if conversion would negatively243 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.244 */
245 public long toMicros(longduration) {246 throw newAbstractMethodError();247 }248
249 /**
250 * Equivalent to251 * {@link#convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.252 *@paramduration the duration253 *@returnthe converted duration,254 * or {@codeLong.MIN_VALUE} if conversion would negatively255 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.256 */
257 public long toMillis(longduration) {258 throw newAbstractMethodError();259 }260
261 /**
262 * Equivalent to263 * {@link#convert(long, TimeUnit) SECONDS.convert(duration, this)}.264 *@paramduration the duration265 *@returnthe converted duration,266 * or {@codeLong.MIN_VALUE} if conversion would negatively267 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.268 */
269 public long toSeconds(longduration) {270 throw newAbstractMethodError();271 }272
273 /**
274 * Equivalent to275 * {@link#convert(long, TimeUnit) MINUTES.convert(duration, this)}.276 *@paramduration the duration277 *@returnthe converted duration,278 * or {@codeLong.MIN_VALUE} if conversion would negatively279 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.280 *@since1.6281 */
282 public long toMinutes(longduration) {283 throw newAbstractMethodError();284 }285
286 /**
287 * Equivalent to288 * {@link#convert(long, TimeUnit) HOURS.convert(duration, this)}.289 *@paramduration the duration290 *@returnthe converted duration,291 * or {@codeLong.MIN_VALUE} if conversion would negatively292 * overflow, or {@codeLong.MAX_VALUE} if it would positively overflow.293 *@since1.6294 */
295 public long toHours(longduration) {296 throw newAbstractMethodError();297 }298
299 /**
300 * Equivalent to301 * {@link#convert(long, TimeUnit) DAYS.convert(duration, this)}.302 *@paramduration the duration303 *@returnthe converted duration304 *@since1.6305 */
306 public long toDays(longduration) {307 throw newAbstractMethodError();308 }309
310 /**
311 * Utility to compute the excess-nanosecond argument to wait,312 * sleep, join.313 *@paramd the duration314 *@paramm the number of milliseconds315 *@returnthe number of nanoseconds316 */
317 abstract int excessNanos(long d, longm);318
319 /**
320 * Performs a timed {@linkObject#wait(long, int) Object.wait}321 * using this time unit.322 * This is a convenience method that converts timeout arguments323 * into the form required by the {@codeObject.wait} method.324 *325 *
For example, you could implement a blocking {@codepoll}326 * method (see {@linkBlockingQueue#poll BlockingQueue.poll})327 * using:328 *329 *
{@code
330 * public synchronized Object poll(long timeout, TimeUnit unit)331 * throws InterruptedException {332 * while (empty) {333 * unit.timedWait(this, timeout);334 * ...335 * }336 * }}
337 *338 *@paramobj the object to wait on339 *@paramtimeout the maximum time to wait. If less than340 * or equal to zero, do not wait at all.341 *@throwsInterruptedException if interrupted while waiting342 */343 public void timedWait(Object obj, longtimeout)344 throwsInterruptedException {345 if (timeout > 0) {346 long ms =toMillis(timeout);347 int ns =excessNanos(timeout, ms);348 obj.wait(ms, ns);349 }350 }351
352 /**
353 * Performs a timed {@linkThread#join(long, int) Thread.join}354 * using this time unit.355 * This is a convenience method that converts time arguments into the356 * form required by the {@codeThread.join} method.357 *358 *@paramthread the thread to wait for359 *@paramtimeout the maximum time to wait. If less than360 * or equal to zero, do not wait at all.361 *@throwsInterruptedException if interrupted while waiting362 */
363 public void timedJoin(Thread thread, longtimeout)364 throwsInterruptedException {365 if (timeout > 0) {366 long ms =toMillis(timeout);367 int ns =excessNanos(timeout, ms);368 thread.join(ms, ns);369 }370 }371
372 /**
373 * Performs a {@linkThread#sleep(long, int) Thread.sleep} using374 * this time unit.375 * This is a convenience method that converts time arguments into the376 * form required by the {@codeThread.sleep} method.377 *378 *@paramtimeout the minimum time to sleep. If less than379 * or equal to zero, do not sleep at all.380 *@throwsInterruptedException if interrupted while sleeping381 */
382 public void sleep(long timeout) throwsInterruptedException {383 if (timeout > 0) {384 long ms =toMillis(timeout);385 int ns =excessNanos(timeout, ms);386 Thread.sleep(ms, ns);387 }388 }389
390 }