ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.19
Committed: Sun Jan 11 23:19:55 2004 UTC (20 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.18: +13 -8 lines
Log Message:
formatting; grammar

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.18 * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/licenses/publicdomain
5 dl 1.2 */
6    
7 tim 1.1 package java.util.concurrent;
8    
9     /**
10 tim 1.6 * 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.
13     * <tt>TimeUnit</tt> is a &quot;featherweight&quot; class.
14     * It does not maintain time information, but only helps organize and
15     * use time representations that may be maintained separately across
16 tim 1.1 * various contexts.
17     *
18 dl 1.12 * <p>This class cannot be directly instantiated. Use the {@link
19     * #SECONDS}, {@link #MILLISECONDS}, {@link #MICROSECONDS}, and {@link
20     * #NANOSECONDS} static instances that provide predefined units of
21     * precision. If you use these frequently, consider statically
22     * importing this class.
23 tim 1.1 *
24 dl 1.19 * <p>A <tt>TimeUnit</tt> is mainly used to inform blocking timeout
25     * methods how the timeout parameter should be interpreted. For
26     * example, the following code will timeout in 50 milliseconds if the
27     * {@link java.util.concurrent.locks.Lock lock} is not available:
28     *
29 tim 1.1 * <pre> Lock lock = ...;
30     * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
31     * </pre>
32     * while this code will timeout in 50 seconds:
33 tim 1.6 * <pre>
34 tim 1.1 * Lock lock = ...;
35     * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
36     * </pre>
37 dl 1.15 *
38     * Note however, that there is no guarantee that a particular timeout
39     * implementation will be able to notice the passage of time at the
40     * same granularity as the given <tt>TimeUnit</tt>.
41 tim 1.1 *
42     * @since 1.5
43 dl 1.4 * @author Doug Lea
44 tim 1.1 */
45     public final class TimeUnit implements java.io.Serializable {
46 dl 1.14 /* ordered indices for each time unit */
47     private static final int NS = 0;
48     private static final int US = 1;
49     private static final int MS = 2;
50     private static final int S = 3;
51    
52     /** quick lookup table for conversion factors */
53     private static final int[] multipliers = { 1,
54     1000,
55     1000*1000,
56     1000*1000*1000 };
57    
58     /** lookup table to check saturation */
59     private static final long[] overflows = {
60     // Note that because we are dividing these down anyway,
61     // we don't have to deal with asymmetry of MIN/MAX values.
62     0, // unused
63     Long.MAX_VALUE / 1000,
64     Long.MAX_VALUE / (1000 * 1000),
65     Long.MAX_VALUE / (1000 * 1000 * 1000) };
66    
67     /** the index of this unit */
68     private int index;
69     /** Common name for unit */
70     private final String unitName;
71    
72     /** private constructor */
73     TimeUnit(int index, String name) {
74     this.index = index;
75     this.unitName = name;
76     }
77    
78     /** Unit for one-second granularities. */
79     public static final TimeUnit SECONDS = new TimeUnit(S, "seconds");
80     /** Unit for one-millisecond granularities. */
81     public static final TimeUnit MILLISECONDS = new TimeUnit(MS, "milliseconds");
82     /** Unit for one-microsecond granularities. */
83     public static final TimeUnit MICROSECONDS = new TimeUnit(US, "microseconds");
84     /** Unit for one-nanosecond granularities. */
85     public static final TimeUnit NANOSECONDS = new TimeUnit(NS, "nanoseconds");
86    
87     /**
88     * Utility method to compute the excess-nanosecond argument to
89 dl 1.15 * wait, sleep, join.
90 dl 1.14 */
91     private int excessNanos(long time, long ms) {
92     if (index == NS)
93     return (int) (time - (ms * multipliers[MS-NS]));
94     else if (index == US)
95     return (int) ((time * multipliers[US-NS]) - (ms * multipliers[MS-NS]));
96     else
97     return 0;
98     }
99 tim 1.1
100     /**
101 dl 1.14 * Perform conversion based on given delta representing the
102 dl 1.13 * difference between units
103     * @param delta the difference in index values of source and target units
104     * @param duration the duration
105     * @return converted duration or saturated value
106     */
107     private static long doConvert(int delta, long duration) {
108     if (delta == 0)
109     return duration;
110     if (delta < 0)
111     return duration / multipliers[-delta];
112     if (duration > overflows[delta])
113     return Long.MAX_VALUE;
114     if (duration < -overflows[delta])
115     return Long.MIN_VALUE;
116     return duration * multipliers[delta];
117     }
118    
119     /**
120 dl 1.17 * Convert the given time duration in the given unit to this
121     * unit. Conversions from finer to coarser granularities
122 dl 1.13 * truncate, so lose precision. For example converting
123     * <tt>999</tt> milliseconds to seconds results in
124     * <tt>0</tt>. Conversions from coarser to finer granularities
125     * with arguments that would numerically overflow saturate to
126     * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
127     * if positive.
128 tim 1.1 *
129     * @param duration the time duration in the given <tt>unit</tt>
130     * @param unit the unit of the <tt>duration</tt> argument
131 dl 1.17 * @return the converted duration in this unit,
132 dl 1.10 * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
133 dl 1.11 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
134 tim 1.1 */
135     public long convert(long duration, TimeUnit unit) {
136 dl 1.13 return doConvert(unit.index - index, duration);
137 dl 1.2 }
138    
139     /**
140 dl 1.12 * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
141 dl 1.2 * @param duration the duration
142 dl 1.13 * @return the converted duration,
143 dl 1.10 * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
144 dl 1.11 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
145 dl 1.13 * @see #convert
146     */
147 dl 1.2 public long toNanos(long duration) {
148 dl 1.13 return doConvert(index, duration);
149     }
150    
151     /**
152     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
153     * @param duration the duration
154     * @return the converted duration,
155     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
156     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
157     * @see #convert
158     */
159     public long toMicros(long duration) {
160     return doConvert(index - US, duration);
161     }
162    
163     /**
164     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
165     * @param duration the duration
166     * @return the converted duration,
167     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
168     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
169     * @see #convert
170     */
171     public long toMillis(long duration) {
172     return doConvert(index - MS, duration);
173     }
174    
175     /**
176     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
177     * @param duration the duration
178     * @return the converted duration.
179     * @see #convert
180     */
181     public long toSeconds(long duration) {
182     return doConvert(index - S, duration);
183 tim 1.1 }
184 tim 1.6
185 tim 1.1 /**
186 dl 1.17 * Perform a timed <tt>Object.wait</tt> using this time unit.
187 dl 1.19 * This is a convenience method that converts timeout arguments
188     * into the form required by the <tt>Object.wait</tt> method.
189     *
190     * <p>For example, you could implement a blocking <tt>poll</tt>
191     * method (see {@link BlockingQueue#poll BlockingQueue.poll}
192     * using:
193     *
194 tim 1.1 * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
195     * while (empty) {
196     * unit.timedWait(this, timeout);
197     * ...
198     * }
199     * }</pre>
200 dl 1.19 *
201 tim 1.1 * @param obj the object to wait on
202 dl 1.10 * @param timeout the maximum time to wait.
203 tim 1.1 * @throws InterruptedException if interrupted while waiting.
204     * @see Object#wait(long, int)
205     */
206     public void timedWait(Object obj, long timeout)
207     throws InterruptedException {
208 dl 1.10 if (timeout > 0) {
209 dl 1.15 long ms = toMillis(timeout);
210 dl 1.10 int ns = excessNanos(timeout, ms);
211     obj.wait(ms, ns);
212     }
213 tim 1.1 }
214    
215     /**
216 dl 1.17 * Perform a timed <tt>Thread.join</tt> using this time unit.
217 tim 1.1 * This is a convenience method that converts time arguments into the
218     * form required by the <tt>Thread.join</tt> method.
219     * @param thread the thread to wait for
220     * @param timeout the maximum time to wait
221     * @throws InterruptedException if interrupted while waiting.
222     * @see Thread#join(long, int)
223     */
224     public void timedJoin(Thread thread, long timeout)
225     throws InterruptedException {
226 dl 1.10 if (timeout > 0) {
227 dl 1.15 long ms = toMillis(timeout);
228 dl 1.10 int ns = excessNanos(timeout, ms);
229     thread.join(ms, ns);
230     }
231 tim 1.1 }
232 tim 1.6
233 tim 1.1 /**
234 dl 1.17 * Perform a <tt>Thread.sleep</tt> using this unit.
235 tim 1.1 * This is a convenience method that converts time arguments into the
236     * form required by the <tt>Thread.sleep</tt> method.
237 tim 1.6 * @param timeout the minimum time to sleep
238 tim 1.1 * @throws InterruptedException if interrupted while sleeping.
239     * @see Thread#sleep
240     */
241     public void sleep(long timeout) throws InterruptedException {
242 dl 1.10 if (timeout > 0) {
243 dl 1.15 long ms = toMillis(timeout);
244 dl 1.10 int ns = excessNanos(timeout, ms);
245     Thread.sleep(ms, ns);
246     }
247 tim 1.1 }
248    
249 dl 1.9 /**
250     * Return the common name for this unit.
251     */
252     public String toString() {
253     return unitName;
254 dl 1.13 }
255    
256     /**
257 dl 1.14 * Resolves instances being deserialized to a single instance per
258     * unit.
259 dl 1.13 */
260 dl 1.14 private Object readResolve() {
261     switch(index) {
262     case NS: return NANOSECONDS;
263     case US: return MICROSECONDS;
264     case MS: return MILLISECONDS;
265     case S: return SECONDS;
266     default: assert(false); return null;
267     }
268 dl 1.9 }
269 tim 1.1 }