1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent; 37 38 import java.util.Objects; 39 40 /** 41 * A {@code TimeUnit} represents time durations at a given unit of 42 * granularity and provides utility methods to convert across units, 43 * and to perform timing and delay operations in these units. A 44 * {@code TimeUnit} does not maintain time information, but only 45 * helps organize and use time representations that may be maintained 46 * separately across various contexts. A nanosecond is defined as one 47 * thousandth of a microsecond, a microsecond as one thousandth of a 48 * millisecond, a millisecond as one thousandth of a second, a minute 49 * as sixty seconds, an hour as sixty minutes, and a day as twenty four 50 * hours. 51 * 52 * <p>A {@code TimeUnit} is mainly used to inform time-based methods 53 * how a given timing parameter should be interpreted. For example, 54 * the following code will timeout in 50 milliseconds if the {@link 55 * java.util.concurrent.locks.Lock lock} is not available: 56 * 57 * <pre> {@code 58 * Lock lock = ...; 59 * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre> 60 * 61 * while this code will timeout in 50 seconds: 62 * <pre> {@code 63 * Lock lock = ...; 64 * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre> 65 * 66 * Note however, that there is no guarantee that a particular timeout 67 * implementation will be able to notice the passage of time at the 68 * same granularity as the given {@code TimeUnit}. 69 * 70 * @since 1.5 71 * @author Doug Lea 72 */ 73 public enum TimeUnit { 74 /** 75 * Time unit representing one thousandth of a microsecond. 76 */ 77 NANOSECONDS { toNanos(long d)78 public long toNanos(long d) { return d; } toMicros(long d)79 public long toMicros(long d) { return d/(C1/C0); } toMillis(long d)80 public long toMillis(long d) { return d/(C2/C0); } toSeconds(long d)81 public long toSeconds(long d) { return d/(C3/C0); } toMinutes(long d)82 public long toMinutes(long d) { return d/(C4/C0); } toHours(long d)83 public long toHours(long d) { return d/(C5/C0); } toDays(long d)84 public long toDays(long d) { return d/(C6/C0); } convert(long d, TimeUnit u)85 public long convert(long d, TimeUnit u) { return u.toNanos(d); } excessNanos(long d, long m)86 int excessNanos(long d, long m) { return (int)(d - (m*C2)); } 87 }, 88 89 /** 90 * Time unit representing one thousandth of a millisecond. 91 */ 92 MICROSECONDS { toNanos(long d)93 public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } toMicros(long d)94 public long toMicros(long d) { return d; } toMillis(long d)95 public long toMillis(long d) { return d/(C2/C1); } toSeconds(long d)96 public long toSeconds(long d) { return d/(C3/C1); } toMinutes(long d)97 public long toMinutes(long d) { return d/(C4/C1); } toHours(long d)98 public long toHours(long d) { return d/(C5/C1); } toDays(long d)99 public long toDays(long d) { return d/(C6/C1); } convert(long d, TimeUnit u)100 public long convert(long d, TimeUnit u) { return u.toMicros(d); } excessNanos(long d, long m)101 int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } 102 }, 103 104 /** 105 * Time unit representing one thousandth of a second. 106 */ 107 MILLISECONDS { toNanos(long d)108 public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } toMicros(long d)109 public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } toMillis(long d)110 public long toMillis(long d) { return d; } toSeconds(long d)111 public long toSeconds(long d) { return d/(C3/C2); } toMinutes(long d)112 public long toMinutes(long d) { return d/(C4/C2); } toHours(long d)113 public long toHours(long d) { return d/(C5/C2); } toDays(long d)114 public long toDays(long d) { return d/(C6/C2); } convert(long d, TimeUnit u)115 public long convert(long d, TimeUnit u) { return u.toMillis(d); } excessNanos(long d, long m)116 int excessNanos(long d, long m) { return 0; } 117 }, 118 119 /** 120 * Time unit representing one second. 121 */ 122 SECONDS { toNanos(long d)123 public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } toMicros(long d)124 public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } toMillis(long d)125 public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } toSeconds(long d)126 public long toSeconds(long d) { return d; } toMinutes(long d)127 public long toMinutes(long d) { return d/(C4/C3); } toHours(long d)128 public long toHours(long d) { return d/(C5/C3); } toDays(long d)129 public long toDays(long d) { return d/(C6/C3); } convert(long d, TimeUnit u)130 public long convert(long d, TimeUnit u) { return u.toSeconds(d); } excessNanos(long d, long m)131 int excessNanos(long d, long m) { return 0; } 132 }, 133 134 /** 135 * Time unit representing sixty seconds. 136 * @since 1.6 137 */ 138 MINUTES { toNanos(long d)139 public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } toMicros(long d)140 public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } toMillis(long d)141 public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } toSeconds(long d)142 public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } toMinutes(long d)143 public long toMinutes(long d) { return d; } toHours(long d)144 public long toHours(long d) { return d/(C5/C4); } toDays(long d)145 public long toDays(long d) { return d/(C6/C4); } convert(long d, TimeUnit u)146 public long convert(long d, TimeUnit u) { return u.toMinutes(d); } excessNanos(long d, long m)147 int excessNanos(long d, long m) { return 0; } 148 }, 149 150 /** 151 * Time unit representing sixty minutes. 152 * @since 1.6 153 */ 154 HOURS { toNanos(long d)155 public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } toMicros(long d)156 public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } toMillis(long d)157 public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } toSeconds(long d)158 public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } toMinutes(long d)159 public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } toHours(long d)160 public long toHours(long d) { return d; } toDays(long d)161 public long toDays(long d) { return d/(C6/C5); } convert(long d, TimeUnit u)162 public long convert(long d, TimeUnit u) { return u.toHours(d); } excessNanos(long d, long m)163 int excessNanos(long d, long m) { return 0; } 164 }, 165 166 /** 167 * Time unit representing twenty four hours. 168 * @since 1.6 169 */ 170 DAYS { toNanos(long d)171 public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } toMicros(long d)172 public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } toMillis(long d)173 public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } toSeconds(long d)174 public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } toMinutes(long d)175 public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } toHours(long d)176 public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } toDays(long d)177 public long toDays(long d) { return d; } convert(long d, TimeUnit u)178 public long convert(long d, TimeUnit u) { return u.toDays(d); } excessNanos(long d, long m)179 int excessNanos(long d, long m) { return 0; } 180 }; 181 182 // Handy constants for conversion methods 183 static final long C0 = 1L; 184 static final long C1 = C0 * 1000L; 185 static final long C2 = C1 * 1000L; 186 static final long C3 = C2 * 1000L; 187 static final long C4 = C3 * 60L; 188 static final long C5 = C4 * 60L; 189 static final long C6 = C5 * 24L; 190 191 static final long MAX = Long.MAX_VALUE; 192 193 /** 194 * Scale d by m, checking for overflow. 195 * This has a short name to make above code more readable. 196 */ x(long d, long m, long over)197 static long x(long d, long m, long over) { 198 if (d > +over) return Long.MAX_VALUE; 199 if (d < -over) return Long.MIN_VALUE; 200 return d * m; 201 } 202 203 // To maintain full signature compatibility with 1.5, and to improve the 204 // clarity of the generated javadoc (see 6287639: Abstract methods in 205 // enum classes should not be listed as abstract), method convert 206 // etc. are not declared abstract but otherwise act as abstract methods. 207 208 /** 209 * Converts the given time duration in the given unit to this unit. 210 * Conversions from finer to coarser granularities truncate, so 211 * lose precision. For example, converting {@code 999} milliseconds 212 * to seconds results in {@code 0}. Conversions from coarser to 213 * finer granularities with arguments that would numerically 214 * overflow saturate to {@code Long.MIN_VALUE} if negative or 215 * {@code Long.MAX_VALUE} if positive. 216 * 217 * <p>For example, to convert 10 minutes to milliseconds, use: 218 * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)} 219 * 220 * @param sourceDuration the time duration in the given {@code sourceUnit} 221 * @param sourceUnit the unit of the {@code sourceDuration} argument 222 * @return the converted duration in this unit, 223 * or {@code Long.MIN_VALUE} if conversion would negatively 224 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 225 */ convert(long sourceDuration, TimeUnit sourceUnit)226 public long convert(long sourceDuration, TimeUnit sourceUnit) { 227 throw new AbstractMethodError(); 228 } 229 230 /** 231 * Equivalent to 232 * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}. 233 * @param duration the duration 234 * @return the converted duration, 235 * or {@code Long.MIN_VALUE} if conversion would negatively 236 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 237 */ toNanos(long duration)238 public long toNanos(long duration) { 239 throw new AbstractMethodError(); 240 } 241 242 /** 243 * Equivalent to 244 * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}. 245 * @param duration the duration 246 * @return the converted duration, 247 * or {@code Long.MIN_VALUE} if conversion would negatively 248 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 249 */ toMicros(long duration)250 public long toMicros(long duration) { 251 throw new AbstractMethodError(); 252 } 253 254 /** 255 * Equivalent to 256 * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}. 257 * @param duration the duration 258 * @return the converted duration, 259 * or {@code Long.MIN_VALUE} if conversion would negatively 260 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 261 */ toMillis(long duration)262 public long toMillis(long duration) { 263 throw new AbstractMethodError(); 264 } 265 266 /** 267 * Equivalent to 268 * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}. 269 * @param duration the duration 270 * @return the converted duration, 271 * or {@code Long.MIN_VALUE} if conversion would negatively 272 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 273 */ toSeconds(long duration)274 public long toSeconds(long duration) { 275 throw new AbstractMethodError(); 276 } 277 278 /** 279 * Equivalent to 280 * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}. 281 * @param duration the duration 282 * @return the converted duration, 283 * or {@code Long.MIN_VALUE} if conversion would negatively 284 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 285 * @since 1.6 286 */ toMinutes(long duration)287 public long toMinutes(long duration) { 288 throw new AbstractMethodError(); 289 } 290 291 /** 292 * Equivalent to 293 * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}. 294 * @param duration the duration 295 * @return the converted duration, 296 * or {@code Long.MIN_VALUE} if conversion would negatively 297 * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. 298 * @since 1.6 299 */ toHours(long duration)300 public long toHours(long duration) { 301 throw new AbstractMethodError(); 302 } 303 304 /** 305 * Equivalent to 306 * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}. 307 * @param duration the duration 308 * @return the converted duration 309 * @since 1.6 310 */ toDays(long duration)311 public long toDays(long duration) { 312 throw new AbstractMethodError(); 313 } 314 315 /** 316 * Utility to compute the excess-nanosecond argument to wait, 317 * sleep, join. 318 * @param d the duration 319 * @param m the number of milliseconds 320 * @return the number of nanoseconds 321 */ excessNanos(long d, long m)322 abstract int excessNanos(long d, long m); 323 324 /** 325 * Performs a timed {@link Object#wait(long, int) Object.wait} 326 * using this time unit. 327 * This is a convenience method that converts timeout arguments 328 * into the form required by the {@code Object.wait} method. 329 * 330 * <p>For example, you could implement a blocking {@code poll} 331 * method (see {@link BlockingQueue#poll BlockingQueue.poll}) 332 * using: 333 * 334 * <pre> {@code 335 * public synchronized Object poll(long timeout, TimeUnit unit) 336 * throws InterruptedException { 337 * while (empty) { 338 * unit.timedWait(this, timeout); 339 * ... 340 * } 341 * }}</pre> 342 * 343 * @param obj the object to wait on 344 * @param timeout the maximum time to wait. If less than 345 * or equal to zero, do not wait at all. 346 * @throws InterruptedException if interrupted while waiting 347 */ timedWait(Object obj, long timeout)348 public void timedWait(Object obj, long timeout) 349 throws InterruptedException { 350 if (timeout > 0) { 351 long ms = toMillis(timeout); 352 int ns = excessNanos(timeout, ms); 353 obj.wait(ms, ns); 354 } 355 } 356 357 /** 358 * Performs a timed {@link Thread#join(long, int) Thread.join} 359 * using this time unit. 360 * This is a convenience method that converts time arguments into the 361 * form required by the {@code Thread.join} method. 362 * 363 * @param thread the thread to wait for 364 * @param timeout the maximum time to wait. If less than 365 * or equal to zero, do not wait at all. 366 * @throws InterruptedException if interrupted while waiting 367 */ timedJoin(Thread thread, long timeout)368 public void timedJoin(Thread thread, long timeout) 369 throws InterruptedException { 370 if (timeout > 0) { 371 long ms = toMillis(timeout); 372 int ns = excessNanos(timeout, ms); 373 thread.join(ms, ns); 374 } 375 } 376 377 /** 378 * Performs a {@link Thread#sleep(long, int) Thread.sleep} using 379 * this time unit. 380 * This is a convenience method that converts time arguments into the 381 * form required by the {@code Thread.sleep} method. 382 * 383 * @param timeout the minimum time to sleep. If less than 384 * or equal to zero, do not sleep at all. 385 * @throws InterruptedException if interrupted while sleeping 386 */ sleep(long timeout)387 public void sleep(long timeout) throws InterruptedException { 388 if (timeout > 0) { 389 long ms = toMillis(timeout); 390 int ns = excessNanos(timeout, ms); 391 Thread.sleep(ms, ns); 392 } 393 } 394 395 // BEGIN Android-removed: OpenJDK 9 ChronoUnit related code. 396 /* 397 /** 398 * Converts this {@code TimeUnit} to the equivalent {@code ChronoUnit}. 399 * 400 * @return the converted equivalent ChronoUnit 401 * @since 9 402 * 403 public ChronoUnit toChronoUnit() { 404 switch (this) { 405 case NANOSECONDS: return ChronoUnit.NANOS; 406 case MICROSECONDS: return ChronoUnit.MICROS; 407 case MILLISECONDS: return ChronoUnit.MILLIS; 408 case SECONDS: return ChronoUnit.SECONDS; 409 case MINUTES: return ChronoUnit.MINUTES; 410 case HOURS: return ChronoUnit.HOURS; 411 case DAYS: return ChronoUnit.DAYS; 412 default: throw new AssertionError(); 413 } 414 } 415 416 /** 417 * Converts a {@code ChronoUnit} to the equivalent {@code TimeUnit}. 418 * 419 * @param chronoUnit the ChronoUnit to convert 420 * @return the converted equivalent TimeUnit 421 * @throws IllegalArgumentException if {@code chronoUnit} has no 422 * equivalent TimeUnit 423 * @throws NullPointerException if {@code chronoUnit} is null 424 * @since 9 425 * 426 public static TimeUnit of(ChronoUnit chronoUnit) { 427 switch (Objects.requireNonNull(chronoUnit, "chronoUnit")) { 428 case NANOS: return TimeUnit.NANOSECONDS; 429 case MICROS: return TimeUnit.MICROSECONDS; 430 case MILLIS: return TimeUnit.MILLISECONDS; 431 case SECONDS: return TimeUnit.SECONDS; 432 case MINUTES: return TimeUnit.MINUTES; 433 case HOURS: return TimeUnit.HOURS; 434 case DAYS: return TimeUnit.DAYS; 435 default: 436 throw new IllegalArgumentException( 437 "No TimeUnit equivalent for " + chronoUnit); 438 } 439 } 440 */ 441 // END Android-removed: OpenJDK 9 ChronoUnit related code. 442 443 } 444