ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.24
Committed: Thu Dec 30 17:57:38 2004 UTC (19 years, 5 months ago) by peierls
Branch: MAIN
Changes since 1.23: +10 -4 lines
Log Message:
Add overflow possibility to @returns entries for toSeconds(), toMinutes(), and toHours()

File Contents

# User Rev Content
1 dl 1.2 /*
2 dl 1.22 * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/licenses/publicdomain
5     */
6 dl 1.2
7 tim 1.1 package java.util.concurrent;
8    
9     /**
10 dl 1.22 * 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. A
13     * <tt>TimeUnit</tt> does not maintain time information, but only
14     * helps organize and use time representations that may be maintained
15 peierls 1.23 * separately across various contexts. A nanosecond is defined as one
16     * thousandth of a microsecond, a microsecond as one thousandth of a
17     * millisecond, a millisecond as one thousandth of a second, a minute
18     * as sixty seconds, an hour as sixty minutes, and a day as twenty four
19 dl 1.22 * hours.
20     *
21     * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
22     * how a given timing parameter should be interpreted. For example,
23     * the following code will timeout in 50 milliseconds if the {@link
24     * java.util.concurrent.locks.Lock lock} is not available:
25     *
26     * <pre> Lock lock = ...;
27     * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
28     * </pre>
29     * while this code will timeout in 50 seconds:
30     * <pre>
31     * Lock lock = ...;
32     * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
33     * </pre>
34     *
35     * Note however, that there is no guarantee that a particular timeout
36     * implementation will be able to notice the passage of time at the
37     * same granularity as the given <tt>TimeUnit</tt>.
38     *
39     * @since 1.5
40     * @author Doug Lea
41     */
42 dl 1.20 public enum TimeUnit {
43 dl 1.22 NANOSECONDS (0) {
44     public long toNanos(long d) { return d; }
45     public long toMicros(long d) { return d/(C1/C0); }
46     public long toMillis(long d) { return d/(C2/C0); }
47     public long toSeconds(long d) { return d/(C3/C0); }
48     public long toMinutes(long d) { return d/(C4/C0); }
49     public long toHours(long d) { return d/(C5/C0); }
50     public long toDays(long d) { return d/(C6/C0); }
51     public long convert(long d, TimeUnit u) { return u.toNanos(d); }
52     int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
53     },
54     MICROSECONDS (1) {
55     public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
56     public long toMicros(long d) { return d; }
57     public long toMillis(long d) { return d/(C2/C1); }
58     public long toSeconds(long d) { return d/(C3/C1); }
59     public long toMinutes(long d) { return d/(C4/C1); }
60     public long toHours(long d) { return d/(C5/C1); }
61     public long toDays(long d) { return d/(C6/C1); }
62     public long convert(long d, TimeUnit u) { return u.toMicros(d); }
63     int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
64     },
65     MILLISECONDS (2) {
66     public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
67     public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
68     public long toMillis(long d) { return d; }
69     public long toSeconds(long d) { return d/(C3/C2); }
70     public long toMinutes(long d) { return d/(C4/C2); }
71     public long toHours(long d) { return d/(C5/C2); }
72     public long toDays(long d) { return d/(C6/C2); }
73     public long convert(long d, TimeUnit u) { return u.toMillis(d); }
74     int excessNanos(long d, long m) { return 0; }
75     },
76     SECONDS (3) {
77     public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
78     public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
79     public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
80     public long toSeconds(long d) { return d; }
81     public long toMinutes(long d) { return d/(C4/C3); }
82     public long toHours(long d) { return d/(C5/C3); }
83     public long toDays(long d) { return d/(C6/C3); }
84     public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
85     int excessNanos(long d, long m) { return 0; }
86     },
87     MINUTES (4) {
88     public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
89     public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
90     public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
91     public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
92     public long toMinutes(long d) { return d; }
93     public long toHours(long d) { return d/(C5/C4); }
94     public long toDays(long d) { return d/(C6/C4); }
95     public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
96     int excessNanos(long d, long m) { return 0; }
97     },
98     HOURS (5) {
99     public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
100     public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
101     public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
102     public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
103     public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
104     public long toHours(long d) { return d; }
105     public long toDays(long d) { return d/(C6/C5); }
106     public long convert(long d, TimeUnit u) { return u.toHours(d); }
107     int excessNanos(long d, long m) { return 0; }
108     },
109     DAYS (6) {
110     public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
111     public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
112     public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
113     public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
114     public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
115     public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
116     public long toDays(long d) { return d; }
117     public long convert(long d, TimeUnit u) { return u.toDays(d); }
118     int excessNanos(long d, long m) { return 0; }
119     };
120    
121     /**
122     * The index of this unit. This value is no longer used in this
123     * version of this class, but is retained for serialization
124     * compatibility with previous version.
125     */
126     private final int index;
127    
128     /** Internal constructor */
129     TimeUnit(int index) {
130     this.index = index;
131     }
132    
133     // Handy constants for conversion methods
134     static final long C0 = 1;
135     static final long C1 = C0 * 1000;
136     static final long C2 = C1 * 1000;
137     static final long C3 = C2 * 1000;
138     static final long C4 = C3 * 60;
139     static final long C5 = C4 * 60;
140     static final long C6 = C5 * 24;
141    
142     static final long MAX = Long.MAX_VALUE;
143    
144     /**
145     * Scale d by m, checking for overflow.
146     * This has a short name to make above code more readable.
147     */
148     static long x(long d, long m, long over) {
149     if (d > over) return Long.MAX_VALUE;
150     if (d < -over) return Long.MIN_VALUE;
151     return d * m;
152     }
153    
154     /**
155     * Convert the given time duration in the given unit to this
156     * unit. Conversions from finer to coarser granularities
157     * truncate, so lose precision. For example converting
158     * <tt>999</tt> milliseconds to seconds results in
159     * <tt>0</tt>. Conversions from coarser to finer granularities
160     * with arguments that would numerically overflow saturate to
161     * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
162     * if positive.
163     *
164     * @param duration the time duration in the given <tt>unit</tt>
165     * @param unit the unit of the <tt>duration</tt> argument
166     * @return the converted duration in this unit,
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     */
170     public abstract long convert(long duration, TimeUnit unit);
171    
172     /**
173     * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
174     * @param duration the duration
175     * @return the converted duration,
176     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
177     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
178     * @see #convert
179     */
180     public abstract long toNanos(long duration);
181    
182     /**
183     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
184     * @param duration the duration
185     * @return the converted duration,
186     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
187     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
188     * @see #convert
189     */
190     public abstract long toMicros(long duration);
191    
192     /**
193     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
194     * @param duration the duration
195     * @return the converted duration,
196     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
197     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
198     * @see #convert
199     */
200     public abstract long toMillis(long duration);
201    
202     /**
203     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
204     * @param duration the duration
205 peierls 1.24 * @return the converted duration,
206     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
207     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
208 dl 1.22 * @see #convert
209     */
210     public abstract long toSeconds(long duration);
211    
212     /**
213     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
214     * @param duration the duration
215 peierls 1.24 * @return the converted duration,
216     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
217     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
218 dl 1.22 * @see #convert
219     */
220     public abstract long toMinutes(long duration);
221    
222     /**
223     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
224     * @param duration the duration
225 peierls 1.24 * @return the converted duration,
226     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
227     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
228 dl 1.22 * @see #convert
229     */
230     public abstract long toHours(long duration);
231    
232     /**
233     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
234     * @param duration the duration
235 peierls 1.24 * @return the converted duration
236 dl 1.22 * @see #convert
237     */
238     public abstract long toDays(long duration);
239    
240     /**
241     * Utility to compute the excess-nanosecond argument to wait,
242     * sleep, join.
243     * @param d the duration
244     * @param m the number of millisecondss
245     * @return the number of nanoseconds
246     */
247     abstract int excessNanos(long d, long m);
248    
249     /**
250     * Perform a timed <tt>Object.wait</tt> using this time unit.
251     * This is a convenience method that converts timeout arguments
252     * into the form required by the <tt>Object.wait</tt> method.
253     *
254     * <p>For example, you could implement a blocking <tt>poll</tt>
255     * method (see {@link BlockingQueue#poll BlockingQueue.poll})
256     * using:
257     *
258     * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
259     * while (empty) {
260     * unit.timedWait(this, timeout);
261     * ...
262     * }
263     * }</pre>
264     *
265     * @param obj the object to wait on
266     * @param timeout the maximum time to wait.
267     * @throws InterruptedException if interrupted while waiting.
268     * @see Object#wait(long, int)
269     */
270     public void timedWait(Object obj, long timeout)
271     throws InterruptedException {
272     if (timeout > 0) {
273     long ms = toMillis(timeout);
274     int ns = excessNanos(timeout, ms);
275     obj.wait(ms, ns);
276     }
277     }
278    
279     /**
280     * Perform a timed <tt>Thread.join</tt> using this time unit.
281     * This is a convenience method that converts time arguments into the
282     * form required by the <tt>Thread.join</tt> method.
283     * @param thread the thread to wait for
284     * @param timeout the maximum time to wait
285     * @throws InterruptedException if interrupted while waiting.
286     * @see Thread#join(long, int)
287     */
288     public void timedJoin(Thread thread, long timeout)
289     throws InterruptedException {
290     if (timeout > 0) {
291     long ms = toMillis(timeout);
292     int ns = excessNanos(timeout, ms);
293     thread.join(ms, ns);
294     }
295     }
296    
297     /**
298     * Perform a <tt>Thread.sleep</tt> using this unit.
299     * This is a convenience method that converts time arguments into the
300     * form required by the <tt>Thread.sleep</tt> method.
301     * @param timeout the minimum time to sleep
302     * @throws InterruptedException if interrupted while sleeping.
303     * @see Thread#sleep
304     */
305     public void sleep(long timeout) throws InterruptedException {
306     if (timeout > 0) {
307     long ms = toMillis(timeout);
308     int ns = excessNanos(timeout, ms);
309     Thread.sleep(ms, ns);
310     }
311     }
312 tim 1.1
313     }