rt/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java
changeset 772 d382dacfd73f
parent 635 e5cc7edead25
child 1891 c8af252ea9eb
     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 +}