ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.11
Committed: Sat Aug 30 14:59:27 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.10: +4 -4 lines
Log Message:
Fix typo

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain. Use, modify, and
4     * redistribute this code in any way without acknowledgement.
5     */
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 tim 1.6 * <p>The <tt>TimeUnit</tt> class cannot be directly instantiated.
19 tim 1.1 * Use the {@link #SECONDS}, {@link #MILLISECONDS}, {@link #MICROSECONDS},
20     * and {@link #NANOSECONDS} static instances that provide predefined
21     * units of precision. If you use these frequently, consider
22     * statically importing this class.
23     *
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     * Note however, that there is no guarantee that a particular lock, in this
37     * case, will be able to notice the passage of time at the same granularity
38     * as the given <tt>TimeUnit</tt>.
39     *
40     * @since 1.5
41     * @spec JSR-166
42 dl 1.11 * @revised $Date: 2003/08/30 14:52:52 $
43 dl 1.10 * @editor $Author: dl $
44 dl 1.4 * @author Doug Lea
45 tim 1.1 */
46     public final class TimeUnit implements java.io.Serializable {
47    
48     /**
49     * Convert the given time duration in the given unit to the
50     * current unit. Conversions from finer to coarser granulaties
51     * truncate, so lose precision. Conversions from coarser to finer
52 dl 1.10 * granularities with arguments that would numerically overflow
53     * saturate to <tt>Long.MIN_VALUE</tt> if negative or
54 dl 1.11 * <tt>Long.MAX_VALUE</tt> if positive.
55 tim 1.1 *
56     * @param duration the time duration in the given <tt>unit</tt>
57     * @param unit the unit of the <tt>duration</tt> argument
58 dl 1.10 * @return the converted duration in the current unit,
59     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
60 dl 1.11 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
61 tim 1.1 */
62     public long convert(long duration, TimeUnit unit) {
63 dl 1.2 if (unit == this)
64     return duration;
65 dl 1.10 else if (index > unit.index)
66 tim 1.1 return duration / multipliers[index - unit.index];
67 dl 1.10 else {
68     int i = unit.index - index;
69     if (duration > overflows[i])
70     return Long.MAX_VALUE;
71     if (duration < -overflows[i])
72     return Long.MIN_VALUE;
73     return duration * multipliers[i];
74     }
75 dl 1.2 }
76    
77     /**
78 dholmes 1.3 * Equivalent to <code>NANOSECONDS.convert(duration, this)</code>.
79 dl 1.2 * @param duration the duration
80     * @return the converted duration.
81 dl 1.10 * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
82 dl 1.11 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
83 dl 1.2 **/
84     public long toNanos(long duration) {
85     if (index == NS)
86     return duration;
87 dl 1.10 if (duration > overflows[index])
88     return Long.MAX_VALUE;
89     if (duration < -overflows[index])
90     return Long.MIN_VALUE;
91     return duration * multipliers[index];
92 tim 1.1 }
93 tim 1.6
94 tim 1.1 /**
95 tim 1.6 * Perform a timed <tt>Object.wait</tt> using the current time unit.
96 tim 1.1 * This is a convenience method that converts timeout arguments into the
97 dl 1.7 * form required by the <tt>Object.wait</tt> method.
98 tim 1.1 * <p>For example, you could implement a blocking <tt>poll</tt> method (see
99     * {@link BlockingQueue#poll BlockingQueue.poll} using:
100     * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
101     * while (empty) {
102     * unit.timedWait(this, timeout);
103     * ...
104     * }
105     * }</pre>
106     * @param obj the object to wait on
107 dl 1.10 * @param timeout the maximum time to wait.
108 tim 1.1 * @throws InterruptedException if interrupted while waiting.
109     * @see Object#wait(long, int)
110     */
111     public void timedWait(Object obj, long timeout)
112     throws InterruptedException {
113 dl 1.10 if (timeout > 0) {
114     long ms = MILLISECONDS.convert(timeout, this);
115     int ns = excessNanos(timeout, ms);
116     obj.wait(ms, ns);
117     }
118 tim 1.1 }
119    
120     /**
121     * Perform a timed <tt>Thread.join</tt> using the current time unit.
122     * This is a convenience method that converts time arguments into the
123     * form required by the <tt>Thread.join</tt> method.
124     * @param thread the thread to wait for
125     * @param timeout the maximum time to wait
126     * @throws InterruptedException if interrupted while waiting.
127     * @see Thread#join(long, int)
128     */
129     public void timedJoin(Thread thread, long timeout)
130     throws InterruptedException {
131 dl 1.10 if (timeout > 0) {
132     long ms = MILLISECONDS.convert(timeout, this);
133     int ns = excessNanos(timeout, ms);
134     thread.join(ms, ns);
135     }
136 tim 1.1 }
137 tim 1.6
138 tim 1.1 /**
139     * Perform a <tt>Thread.sleep</tt> using the current time unit.
140     * This is a convenience method that converts time arguments into the
141     * form required by the <tt>Thread.sleep</tt> method.
142 tim 1.6 * @param timeout the minimum time to sleep
143 tim 1.1 * @throws InterruptedException if interrupted while sleeping.
144     * @see Thread#sleep
145     */
146     public void sleep(long timeout) throws InterruptedException {
147 dl 1.10 if (timeout > 0) {
148     long ms = MILLISECONDS.convert(timeout, this);
149     int ns = excessNanos(timeout, ms);
150     Thread.sleep(ms, ns);
151     }
152 tim 1.1 }
153    
154 dl 1.9 /**
155     * Return the common name for this unit.
156     */
157     public String toString() {
158     return unitName;
159     }
160    
161     private final String unitName;
162    
163 tim 1.1 /* ordered indices for each time unit */
164     private static final int NS = 0;
165     private static final int US = 1;
166     private static final int MS = 2;
167     private static final int S = 3;
168    
169 dl 1.4 /** quick lookup table for conversion factors */
170 dl 1.10 static final int[] multipliers = { 1,
171     1000,
172     1000*1000,
173     1000*1000*1000 };
174    
175     /** lookup table to check saturation */
176     static final long[] overflows = {
177     // Note that because we are dividing these down anyway,
178     // we don't have to deal with asymmetry of MIN/MAX values.
179     0, // unused
180     Long.MAX_VALUE / 1000,
181     Long.MAX_VALUE / (1000 * 1000),
182     Long.MAX_VALUE / (1000 * 1000 * 1000) };
183 tim 1.1
184 dl 1.4 /** the index of this unit */
185 tim 1.1 int index;
186    
187     /** private constructor */
188 dl 1.9 TimeUnit(int index, String name) {
189     this.index = index;
190     this.unitName = name;
191     }
192 tim 1.1
193 tim 1.6 /**
194 tim 1.1 * Utility method to compute the excess-nanosecond argument to
195 dl 1.7 * wait, sleep, join. The results may overflow, so public methods
196     * invoking this should document possible overflow unless
197     * overflow is known not to be possible for the given arguments.
198 tim 1.1 */
199     private int excessNanos(long time, long ms) {
200 tim 1.6 if (index == NS)
201 tim 1.1 return (int) (time - (ms * multipliers[MS-NS]));
202 tim 1.6 else if (index == US)
203 tim 1.1 return (int) ((time * multipliers[US-NS]) - (ms * multipliers[MS-NS]));
204 tim 1.6 else
205 tim 1.1 return 0;
206     }
207    
208 tim 1.8 /** Unit for one-second granularities. */
209 dl 1.9 public static final TimeUnit SECONDS = new TimeUnit(S, "seconds");
210 tim 1.1
211 tim 1.8 /** Unit for one-millisecond granularities. */
212 dl 1.9 public static final TimeUnit MILLISECONDS = new TimeUnit(MS, "milliseconds");
213 tim 1.1
214 tim 1.8 /** Unit for one-microsecond granularities. */
215 dl 1.9 public static final TimeUnit MICROSECONDS = new TimeUnit(US, "microseconds");
216 tim 1.1
217 tim 1.8 /** Unit for one-nanosecond granularities. */
218 dl 1.9 public static final TimeUnit NANOSECONDS = new TimeUnit(NS, "nanoseconds");
219 tim 1.1
220     }