ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.18
Committed: Sat Dec 27 19:26:26 2003 UTC (20 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.17: +2 -2 lines
Log Message:
Headers reference Creative Commons

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