KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > TimeUnit


1 /*
2  * @(#)TimeUnit.java 1.6 04/02/09
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent;
9
10 /**
11  * A <tt>TimeUnit</tt> represents time durations at a given unit of
12  * granularity and provides utility methods to convert across units,
13  * and to perform timing and delay operations in these units. A
14  * <tt>TimeUnit</tt> does not maintain time information, but only
15  * helps organize and use time representations that may be maintained
16  * separately across various contexts.
17  *
18  * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
19  * how a given timing parameter should be interpreted. For example,
20  * the following code will timeout in 50 milliseconds if the {@link
21  * java.util.concurrent.locks.Lock lock} is not available:
22  *
23  * <pre> Lock lock = ...;
24  * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
25  * </pre>
26  * while this code will timeout in 50 seconds:
27  * <pre>
28  * Lock lock = ...;
29  * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
30  * </pre>
31  *
32  * Note however, that there is no guarantee that a particular timeout
33  * implementation will be able to notice the passage of time at the
34  * same granularity as the given <tt>TimeUnit</tt>.
35  *
36  * @since 1.5
37  * @author Doug Lea
38  */

39 public enum TimeUnit {
40     NANOSECONDS(0), MICROSECONDS(1), MILLISECONDS(2), SECONDS(3);
41
42     /** the index of this unit */
43     private final int index;
44
45     /** Internal constructor */
46     TimeUnit(int index) {
47         this.index = index;
48     }
49
50     /** Lookup table for conversion factors */
51     private static final int[] multipliers = {
52         1,
53         1000,
54         1000 * 1000,
55         1000 * 1000 * 1000
56     };
57     
58     /**
59      * Lookup table to check saturation. Note that because we are
60      * dividing these down, we don't have to deal with asymmetry of
61      * MIN/MAX values.
62      */

63     private static final long[] overflows = {
64         0, // unused
65
Long.MAX_VALUE / 1000,
66         Long.MAX_VALUE / (1000 * 1000),
67         Long.MAX_VALUE / (1000 * 1000 * 1000)
68     };
69
70     /**
71      * Perform conversion based on given delta representing the
72      * difference between units
73      * @param delta the difference in index values of source and target units
74      * @param duration the duration
75      * @return converted duration or saturated value
76      */

77     private static long doConvert(int delta, long duration) {
78         if (delta == 0)
79             return duration;
80         if (delta < 0)
81             return duration / multipliers[-delta];
82         if (duration > overflows[delta])
83             return Long.MAX_VALUE;
84         if (duration < -overflows[delta])
85             return Long.MIN_VALUE;
86         return duration * multipliers[delta];
87     }
88
89     /**
90      * Convert the given time duration in the given unit to this
91      * unit. Conversions from finer to coarser granularities
92      * truncate, so lose precision. For example converting
93      * <tt>999</tt> milliseconds to seconds results in
94      * <tt>0</tt>. Conversions from coarser to finer granularities
95      * with arguments that would numerically overflow saturate to
96      * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
97      * if positive.
98      *
99      * @param duration the time duration in the given <tt>unit</tt>
100      * @param unit the unit of the <tt>duration</tt> argument
101      * @return the converted duration in this unit,
102      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
103      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
104      */

105     public long convert(long duration, TimeUnit JavaDoc unit) {
106         return doConvert(unit.index - index, duration);
107     }
108
109     /**
110      * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
111      * @param duration the duration
112      * @return the converted duration,
113      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
114      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
115      * @see #convert
116      */

117     public long toNanos(long duration) {
118         return doConvert(index, duration);
119     }
120
121     /**
122      * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
123      * @param duration the duration
124      * @return the converted duration,
125      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
126      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
127      * @see #convert
128      */

129     public long toMicros(long duration) {
130         return doConvert(index - MICROSECONDS.index, duration);
131     }
132
133     /**
134      * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
135      * @param duration the duration
136      * @return the converted duration,
137      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
138      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
139      * @see #convert
140      */

141     public long toMillis(long duration) {
142         return doConvert(index - MILLISECONDS.index, duration);
143     }
144
145     /**
146      * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
147      * @param duration the duration
148      * @return the converted duration.
149      * @see #convert
150      */

151     public long toSeconds(long duration) {
152         return doConvert(index - SECONDS.index, duration);
153     }
154
155
156     /**
157      * Utility method to compute the excess-nanosecond argument to
158      * wait, sleep, join.
159      */

160     private int excessNanos(long time, long ms) {
161         if (this == NANOSECONDS)
162             return (int) (time - (ms * 1000 * 1000));
163         if (this == MICROSECONDS)
164             return (int) ((time * 1000) - (ms * 1000 * 1000));
165         return 0;
166     }
167
168     /**
169      * Perform a timed <tt>Object.wait</tt> using this time unit.
170      * This is a convenience method that converts timeout arguments
171      * into the form required by the <tt>Object.wait</tt> method.
172      *
173      * <p>For example, you could implement a blocking <tt>poll</tt>
174      * method (see {@link BlockingQueue#poll BlockingQueue.poll})
175      * using:
176      *
177      * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
178      * while (empty) {
179      * unit.timedWait(this, timeout);
180      * ...
181      * }
182      * }</pre>
183      *
184      * @param obj the object to wait on
185      * @param timeout the maximum time to wait.
186      * @throws InterruptedException if interrupted while waiting.
187      * @see Object#wait(long, int)
188      */

189     public void timedWait(Object JavaDoc obj, long timeout)
190         throws InterruptedException JavaDoc {
191         if (timeout > 0) {
192             long ms = toMillis(timeout);
193             int ns = excessNanos(timeout, ms);
194             obj.wait(ms, ns);
195         }
196     }
197
198     /**
199      * Perform a timed <tt>Thread.join</tt> using this time unit.
200      * This is a convenience method that converts time arguments into the
201      * form required by the <tt>Thread.join</tt> method.
202      * @param thread the thread to wait for
203      * @param timeout the maximum time to wait
204      * @throws InterruptedException if interrupted while waiting.
205      * @see Thread#join(long, int)
206      */

207     public void timedJoin(Thread JavaDoc thread, long timeout)
208         throws InterruptedException JavaDoc {
209         if (timeout > 0) {
210             long ms = toMillis(timeout);
211             int ns = excessNanos(timeout, ms);
212             thread.join(ms, ns);
213         }
214     }
215
216     /**
217      * Perform a <tt>Thread.sleep</tt> using this unit.
218      * This is a convenience method that converts time arguments into the
219      * form required by the <tt>Thread.sleep</tt> method.
220      * @param timeout the minimum time to sleep
221      * @throws InterruptedException if interrupted while sleeping.
222      * @see Thread#sleep
223      */

224     public void sleep(long timeout) throws InterruptedException JavaDoc {
225         if (timeout > 0) {
226             long ms = toMillis(timeout);
227             int ns = excessNanos(timeout, ms);
228             Thread.sleep(ms, ns);
229         }
230     }
231
232 }
233
Popular Tags