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

Save This Page
Home » openjdk-7 » java » util » concurrent » [javadoc | source]