1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,367 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent;
1.40 +
1.41 +/**
1.42 + * A <tt>TimeUnit</tt> represents time durations at a given unit of
1.43 + * granularity and provides utility methods to convert across units,
1.44 + * and to perform timing and delay operations in these units. A
1.45 + * <tt>TimeUnit</tt> does not maintain time information, but only
1.46 + * helps organize and use time representations that may be maintained
1.47 + * separately across various contexts. A nanosecond is defined as one
1.48 + * thousandth of a microsecond, a microsecond as one thousandth of a
1.49 + * millisecond, a millisecond as one thousandth of a second, a minute
1.50 + * as sixty seconds, an hour as sixty minutes, and a day as twenty four
1.51 + * hours.
1.52 + *
1.53 + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
1.54 + * how a given timing parameter should be interpreted. For example,
1.55 + * the following code will timeout in 50 milliseconds if the {@link
1.56 + * java.util.concurrent.locks.Lock lock} is not available:
1.57 + *
1.58 + * <pre> Lock lock = ...;
1.59 + * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
1.60 + * </pre>
1.61 + * while this code will timeout in 50 seconds:
1.62 + * <pre>
1.63 + * Lock lock = ...;
1.64 + * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...
1.65 + * </pre>
1.66 + *
1.67 + * Note however, that there is no guarantee that a particular timeout
1.68 + * implementation will be able to notice the passage of time at the
1.69 + * same granularity as the given <tt>TimeUnit</tt>.
1.70 + *
1.71 + * @since 1.5
1.72 + * @author Doug Lea
1.73 + */
1.74 +public enum TimeUnit {
1.75 + NANOSECONDS {
1.76 + public long toNanos(long d) { return d; }
1.77 + public long toMicros(long d) { return d/(C1/C0); }
1.78 + public long toMillis(long d) { return d/(C2/C0); }
1.79 + public long toSeconds(long d) { return d/(C3/C0); }
1.80 + public long toMinutes(long d) { return d/(C4/C0); }
1.81 + public long toHours(long d) { return d/(C5/C0); }
1.82 + public long toDays(long d) { return d/(C6/C0); }
1.83 + public long convert(long d, TimeUnit u) { return u.toNanos(d); }
1.84 + int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
1.85 + },
1.86 + MICROSECONDS {
1.87 + public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
1.88 + public long toMicros(long d) { return d; }
1.89 + public long toMillis(long d) { return d/(C2/C1); }
1.90 + public long toSeconds(long d) { return d/(C3/C1); }
1.91 + public long toMinutes(long d) { return d/(C4/C1); }
1.92 + public long toHours(long d) { return d/(C5/C1); }
1.93 + public long toDays(long d) { return d/(C6/C1); }
1.94 + public long convert(long d, TimeUnit u) { return u.toMicros(d); }
1.95 + int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
1.96 + },
1.97 + MILLISECONDS {
1.98 + public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
1.99 + public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
1.100 + public long toMillis(long d) { return d; }
1.101 + public long toSeconds(long d) { return d/(C3/C2); }
1.102 + public long toMinutes(long d) { return d/(C4/C2); }
1.103 + public long toHours(long d) { return d/(C5/C2); }
1.104 + public long toDays(long d) { return d/(C6/C2); }
1.105 + public long convert(long d, TimeUnit u) { return u.toMillis(d); }
1.106 + int excessNanos(long d, long m) { return 0; }
1.107 + },
1.108 + SECONDS {
1.109 + public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
1.110 + public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
1.111 + public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
1.112 + public long toSeconds(long d) { return d; }
1.113 + public long toMinutes(long d) { return d/(C4/C3); }
1.114 + public long toHours(long d) { return d/(C5/C3); }
1.115 + public long toDays(long d) { return d/(C6/C3); }
1.116 + public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
1.117 + int excessNanos(long d, long m) { return 0; }
1.118 + },
1.119 + MINUTES {
1.120 + public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
1.121 + public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
1.122 + public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
1.123 + public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
1.124 + public long toMinutes(long d) { return d; }
1.125 + public long toHours(long d) { return d/(C5/C4); }
1.126 + public long toDays(long d) { return d/(C6/C4); }
1.127 + public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
1.128 + int excessNanos(long d, long m) { return 0; }
1.129 + },
1.130 + HOURS {
1.131 + public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
1.132 + public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
1.133 + public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
1.134 + public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
1.135 + public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
1.136 + public long toHours(long d) { return d; }
1.137 + public long toDays(long d) { return d/(C6/C5); }
1.138 + public long convert(long d, TimeUnit u) { return u.toHours(d); }
1.139 + int excessNanos(long d, long m) { return 0; }
1.140 + },
1.141 + DAYS {
1.142 + public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
1.143 + public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
1.144 + public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
1.145 + public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
1.146 + public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
1.147 + public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
1.148 + public long toDays(long d) { return d; }
1.149 + public long convert(long d, TimeUnit u) { return u.toDays(d); }
1.150 + int excessNanos(long d, long m) { return 0; }
1.151 + };
1.152 +
1.153 + // Handy constants for conversion methods
1.154 + static final long C0 = 1L;
1.155 + static final long C1 = C0 * 1000L;
1.156 + static final long C2 = C1 * 1000L;
1.157 + static final long C3 = C2 * 1000L;
1.158 + static final long C4 = C3 * 60L;
1.159 + static final long C5 = C4 * 60L;
1.160 + static final long C6 = C5 * 24L;
1.161 +
1.162 + static final long MAX = Long.MAX_VALUE;
1.163 +
1.164 + /**
1.165 + * Scale d by m, checking for overflow.
1.166 + * This has a short name to make above code more readable.
1.167 + */
1.168 + static long x(long d, long m, long over) {
1.169 + if (d > over) return Long.MAX_VALUE;
1.170 + if (d < -over) return Long.MIN_VALUE;
1.171 + return d * m;
1.172 + }
1.173 +
1.174 + // To maintain full signature compatibility with 1.5, and to improve the
1.175 + // clarity of the generated javadoc (see 6287639: Abstract methods in
1.176 + // enum classes should not be listed as abstract), method convert
1.177 + // etc. are not declared abstract but otherwise act as abstract methods.
1.178 +
1.179 + /**
1.180 + * Convert the given time duration in the given unit to this
1.181 + * unit. Conversions from finer to coarser granularities
1.182 + * truncate, so lose precision. For example converting
1.183 + * <tt>999</tt> milliseconds to seconds results in
1.184 + * <tt>0</tt>. Conversions from coarser to finer granularities
1.185 + * with arguments that would numerically overflow saturate to
1.186 + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
1.187 + * if positive.
1.188 + *
1.189 + * <p>For example, to convert 10 minutes to milliseconds, use:
1.190 + * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
1.191 + *
1.192 + * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
1.193 + * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
1.194 + * @return the converted duration in this unit,
1.195 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.196 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.197 + */
1.198 + public long convert(long sourceDuration, TimeUnit sourceUnit) {
1.199 + throw new AbstractMethodError();
1.200 + }
1.201 +
1.202 + /**
1.203 + * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
1.204 + * @param duration the duration
1.205 + * @return the converted duration,
1.206 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.207 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.208 + * @see #convert
1.209 + */
1.210 + public long toNanos(long duration) {
1.211 + throw new AbstractMethodError();
1.212 + }
1.213 +
1.214 + /**
1.215 + * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
1.216 + * @param duration the duration
1.217 + * @return the converted duration,
1.218 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.219 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.220 + * @see #convert
1.221 + */
1.222 + public long toMicros(long duration) {
1.223 + throw new AbstractMethodError();
1.224 + }
1.225 +
1.226 + /**
1.227 + * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
1.228 + * @param duration the duration
1.229 + * @return the converted duration,
1.230 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.231 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.232 + * @see #convert
1.233 + */
1.234 + public long toMillis(long duration) {
1.235 + throw new AbstractMethodError();
1.236 + }
1.237 +
1.238 + /**
1.239 + * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
1.240 + * @param duration the duration
1.241 + * @return the converted duration,
1.242 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.243 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.244 + * @see #convert
1.245 + */
1.246 + public long toSeconds(long duration) {
1.247 + throw new AbstractMethodError();
1.248 + }
1.249 +
1.250 + /**
1.251 + * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
1.252 + * @param duration the duration
1.253 + * @return the converted duration,
1.254 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.255 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.256 + * @see #convert
1.257 + * @since 1.6
1.258 + */
1.259 + public long toMinutes(long duration) {
1.260 + throw new AbstractMethodError();
1.261 + }
1.262 +
1.263 + /**
1.264 + * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
1.265 + * @param duration the duration
1.266 + * @return the converted duration,
1.267 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
1.268 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
1.269 + * @see #convert
1.270 + * @since 1.6
1.271 + */
1.272 + public long toHours(long duration) {
1.273 + throw new AbstractMethodError();
1.274 + }
1.275 +
1.276 + /**
1.277 + * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
1.278 + * @param duration the duration
1.279 + * @return the converted duration
1.280 + * @see #convert
1.281 + * @since 1.6
1.282 + */
1.283 + public long toDays(long duration) {
1.284 + throw new AbstractMethodError();
1.285 + }
1.286 +
1.287 + /**
1.288 + * Utility to compute the excess-nanosecond argument to wait,
1.289 + * sleep, join.
1.290 + * @param d the duration
1.291 + * @param m the number of milliseconds
1.292 + * @return the number of nanoseconds
1.293 + */
1.294 + abstract int excessNanos(long d, long m);
1.295 +
1.296 + /**
1.297 + * Performs a timed {@link Object#wait(long, int) Object.wait}
1.298 + * using this time unit.
1.299 + * This is a convenience method that converts timeout arguments
1.300 + * into the form required by the <tt>Object.wait</tt> method.
1.301 + *
1.302 + * <p>For example, you could implement a blocking <tt>poll</tt>
1.303 + * method (see {@link BlockingQueue#poll BlockingQueue.poll})
1.304 + * using:
1.305 + *
1.306 + * <pre> {@code
1.307 + * public synchronized Object poll(long timeout, TimeUnit unit)
1.308 + * throws InterruptedException {
1.309 + * while (empty) {
1.310 + * unit.timedWait(this, timeout);
1.311 + * ...
1.312 + * }
1.313 + * }}</pre>
1.314 + *
1.315 + * @param obj the object to wait on
1.316 + * @param timeout the maximum time to wait. If less than
1.317 + * or equal to zero, do not wait at all.
1.318 + * @throws InterruptedException if interrupted while waiting
1.319 + */
1.320 + public void timedWait(Object obj, long timeout)
1.321 + throws InterruptedException {
1.322 + if (timeout > 0) {
1.323 + long ms = toMillis(timeout);
1.324 + int ns = excessNanos(timeout, ms);
1.325 + obj.wait(ms, ns);
1.326 + }
1.327 + }
1.328 +
1.329 + /**
1.330 + * Performs a timed {@link Thread#join(long, int) Thread.join}
1.331 + * using this time unit.
1.332 + * This is a convenience method that converts time arguments into the
1.333 + * form required by the <tt>Thread.join</tt> method.
1.334 + *
1.335 + * @param thread the thread to wait for
1.336 + * @param timeout the maximum time to wait. If less than
1.337 + * or equal to zero, do not wait at all.
1.338 + * @throws InterruptedException if interrupted while waiting
1.339 + */
1.340 +// public void timedJoin(Thread thread, long timeout)
1.341 +// throws InterruptedException {
1.342 +// if (timeout > 0) {
1.343 +// long ms = toMillis(timeout);
1.344 +// int ns = excessNanos(timeout, ms);
1.345 +// thread.join(ms, ns);
1.346 +// }
1.347 +// }
1.348 +
1.349 + /**
1.350 + * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
1.351 + * this time unit.
1.352 + * This is a convenience method that converts time arguments into the
1.353 + * form required by the <tt>Thread.sleep</tt> method.
1.354 + *
1.355 + * @param timeout the minimum time to sleep. If less than
1.356 + * or equal to zero, do not sleep at all.
1.357 + * @throws InterruptedException if interrupted while sleeping
1.358 + */
1.359 + public void sleep(long timeout) throws InterruptedException {
1.360 + if (timeout > 0) {
1.361 + long ms = toMillis(timeout);
1.362 + int ns = excessNanos(timeout, ms);
1.363 + Object o = new Object();
1.364 + synchronized (o) {
1.365 + o.wait(ms, ns);
1.366 + }
1.367 + }
1.368 + }
1.369 +
1.370 +}