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