GNU Classpath (0.98) | |
Frames | No Frames |
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: */ 6: 7: package java.util.concurrent; 8: 9: /** 10: * A <tt>TimeUnit</tt> 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: * <tt>TimeUnit</tt> 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 <tt>TimeUnit</tt> 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> Lock lock = ...; 27: * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ... 28: * </pre> 29: * while this code will timeout in 50 seconds: 30: * <pre> 31: * Lock lock = ...; 32: * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ... 33: * </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 <tt>TimeUnit</tt>. 38: * 39: * @since 1.5 40: * @author Doug Lea 41: */ 42: public enum TimeUnit { 43: NANOSECONDS { 44: public long toNanos(long d) { return d; } 45: public long toMicros(long d) { return d/(C1/C0); } 46: public long toMillis(long d) { return d/(C2/C0); } 47: public long toSeconds(long d) { return d/(C3/C0); } 48: public long toMinutes(long d) { return d/(C4/C0); } 49: public long toHours(long d) { return d/(C5/C0); } 50: public long toDays(long d) { return d/(C6/C0); } 51: public long convert(long d, TimeUnit u) { return u.toNanos(d); } 52: int excessNanos(long d, long m) { return (int)(d - (m*C2)); } 53: }, 54: MICROSECONDS { 55: public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } 56: public long toMicros(long d) { return d; } 57: public long toMillis(long d) { return d/(C2/C1); } 58: public long toSeconds(long d) { return d/(C3/C1); } 59: public long toMinutes(long d) { return d/(C4/C1); } 60: public long toHours(long d) { return d/(C5/C1); } 61: public long toDays(long d) { return d/(C6/C1); } 62: public long convert(long d, TimeUnit u) { return u.toMicros(d); } 63: int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } 64: }, 65: MILLISECONDS { 66: public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } 67: public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } 68: public long toMillis(long d) { return d; } 69: public long toSeconds(long d) { return d/(C3/C2); } 70: public long toMinutes(long d) { return d/(C4/C2); } 71: public long toHours(long d) { return d/(C5/C2); } 72: public long toDays(long d) { return d/(C6/C2); } 73: public long convert(long d, TimeUnit u) { return u.toMillis(d); } 74: int excessNanos(long d, long m) { return 0; } 75: }, 76: SECONDS { 77: public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } 78: public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } 79: public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } 80: public long toSeconds(long d) { return d; } 81: public long toMinutes(long d) { return d/(C4/C3); } 82: public long toHours(long d) { return d/(C5/C3); } 83: public long toDays(long d) { return d/(C6/C3); } 84: public long convert(long d, TimeUnit u) { return u.toSeconds(d); } 85: int excessNanos(long d, long m) { return 0; } 86: }, 87: MINUTES { 88: public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } 89: public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } 90: public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } 91: public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } 92: public long toMinutes(long d) { return d; } 93: public long toHours(long d) { return d/(C5/C4); } 94: public long toDays(long d) { return d/(C6/C4); } 95: public long convert(long d, TimeUnit u) { return u.toMinutes(d); } 96: int excessNanos(long d, long m) { return 0; } 97: }, 98: HOURS { 99: public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } 100: public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } 101: public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } 102: public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } 103: public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } 104: public long toHours(long d) { return d; } 105: public long toDays(long d) { return d/(C6/C5); } 106: public long convert(long d, TimeUnit u) { return u.toHours(d); } 107: int excessNanos(long d, long m) { return 0; } 108: }, 109: DAYS { 110: public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } 111: public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } 112: public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } 113: public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } 114: 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: // Handy constants for conversion methods 122: static final long C0 = 1L; 123: static final long C1 = C0 * 1000L; 124: static final long C2 = C1 * 1000L; 125: static final long C3 = C2 * 1000L; 126: static final long C4 = C3 * 60L; 127: static final long C5 = C4 * 60L; 128: static final long C6 = C5 * 24L; 129: 130: static final long MAX = Long.MAX_VALUE; 131: 132: /** 133: * Scale d by m, checking for overflow. 134: * This has a short name to make above code more readable. 135: */ 136: static long x(long d, long m, long over) { 137: if (d > over) return Long.MAX_VALUE; 138: if (d < -over) return Long.MIN_VALUE; 139: return d * m; 140: } 141: 142: // To maintain full signature compatibility with 1.5, and to improve the 143: // clarity of the generated javadoc (see 6287639: Abstract methods in 144: // enum classes should not be listed as abstract), method convert 145: // etc. are not declared abstract but otherwise act as abstract methods. 146: 147: /** 148: * Convert the given time duration in the given unit to this 149: * unit. Conversions from finer to coarser granularities 150: * truncate, so lose precision. For example converting 151: * <tt>999</tt> milliseconds to seconds results in 152: * <tt>0</tt>. Conversions from coarser to finer granularities 153: * with arguments that would numerically overflow saturate to 154: * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> 155: * if positive. 156: * 157: * <p>For example, to convert 10 minutes to milliseconds, use: 158: * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt> 159: * 160: * @param sourceDuration the time duration in the given <tt>sourceUnit</tt> 161: * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument 162: * @return the converted duration in this unit, 163: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 164: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 165: */ 166: public long convert(long sourceDuration, TimeUnit sourceUnit) { 167: throw new AbstractMethodError(); 168: } 169: 170: /** 171: * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>. 172: * @param duration the duration 173: * @return the converted duration, 174: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 175: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 176: * @see #convert 177: */ 178: public long toNanos(long duration) { 179: throw new AbstractMethodError(); 180: } 181: 182: /** 183: * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>. 184: * @param duration the duration 185: * @return the converted duration, 186: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 187: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 188: * @see #convert 189: */ 190: public long toMicros(long duration) { 191: throw new AbstractMethodError(); 192: } 193: 194: /** 195: * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>. 196: * @param duration the duration 197: * @return the converted duration, 198: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 199: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 200: * @see #convert 201: */ 202: public long toMillis(long duration) { 203: throw new AbstractMethodError(); 204: } 205: 206: /** 207: * Equivalent to <tt>SECONDS.convert(duration, this)</tt>. 208: * @param duration the duration 209: * @return the converted duration, 210: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 211: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 212: * @see #convert 213: */ 214: public long toSeconds(long duration) { 215: throw new AbstractMethodError(); 216: } 217: 218: /** 219: * Equivalent to <tt>MINUTES.convert(duration, this)</tt>. 220: * @param duration the duration 221: * @return the converted duration, 222: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 223: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 224: * @see #convert 225: * @since 1.6 226: */ 227: public long toMinutes(long duration) { 228: throw new AbstractMethodError(); 229: } 230: 231: /** 232: * Equivalent to <tt>HOURS.convert(duration, this)</tt>. 233: * @param duration the duration 234: * @return the converted duration, 235: * or <tt>Long.MIN_VALUE</tt> if conversion would negatively 236: * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. 237: * @see #convert 238: * @since 1.6 239: */ 240: public long toHours(long duration) { 241: throw new AbstractMethodError(); 242: } 243: 244: /** 245: * Equivalent to <tt>DAYS.convert(duration, this)</tt>. 246: * @param duration the duration 247: * @return the converted duration 248: * @see #convert 249: * @since 1.6 250: */ 251: public long toDays(long duration) { 252: throw new AbstractMethodError(); 253: } 254: 255: /** 256: * Utility to compute the excess-nanosecond argument to wait, 257: * sleep, join. 258: * @param d the duration 259: * @param m the number of milliseconds 260: * @return the number of nanoseconds 261: */ 262: abstract int excessNanos(long d, long m); 263: 264: /** 265: * Performs a timed <tt>Object.wait</tt> using this time unit. 266: * This is a convenience method that converts timeout arguments 267: * into the form required by the <tt>Object.wait</tt> method. 268: * 269: * <p>For example, you could implement a blocking <tt>poll</tt> 270: * method (see {@link BlockingQueue#poll BlockingQueue.poll}) 271: * using: 272: * 273: * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException { 274: * while (empty) { 275: * unit.timedWait(this, timeout); 276: * ... 277: * } 278: * }</pre> 279: * 280: * @param obj the object to wait on 281: * @param timeout the maximum time to wait. If less than 282: * or equal to zero, do not wait at all. 283: * @throws InterruptedException if interrupted while waiting. 284: * @see Object#wait(long, int) 285: */ 286: public void timedWait(Object obj, long timeout) 287: throws InterruptedException { 288: if (timeout > 0) { 289: long ms = toMillis(timeout); 290: int ns = excessNanos(timeout, ms); 291: obj.wait(ms, ns); 292: } 293: } 294: 295: /** 296: * Performs a timed <tt>Thread.join</tt> using this time unit. 297: * This is a convenience method that converts time arguments into the 298: * form required by the <tt>Thread.join</tt> method. 299: * @param thread the thread to wait for 300: * @param timeout the maximum time to wait. If less than 301: * or equal to zero, do not wait at all. 302: * @throws InterruptedException if interrupted while waiting. 303: * @see Thread#join(long, int) 304: */ 305: public void timedJoin(Thread thread, long timeout) 306: throws InterruptedException { 307: if (timeout > 0) { 308: long ms = toMillis(timeout); 309: int ns = excessNanos(timeout, ms); 310: thread.join(ms, ns); 311: } 312: } 313: 314: /** 315: * Performs a <tt>Thread.sleep</tt> using this unit. 316: * This is a convenience method that converts time arguments into the 317: * form required by the <tt>Thread.sleep</tt> method. 318: * @param timeout the minimum time to sleep. If less than 319: * or equal to zero, do not sleep at all. 320: * @throws InterruptedException if interrupted while sleeping. 321: * @see Thread#sleep 322: */ 323: public void sleep(long timeout) throws InterruptedException { 324: if (timeout > 0) { 325: long ms = toMillis(timeout); 326: int ns = excessNanos(timeout, ms); 327: Thread.sleep(ms, ns); 328: } 329: } 330: 331: }
GNU Classpath (0.98) |