ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.12
Committed: Sun Aug 31 13:33:14 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.11: +15 -20 lines
Log Message:
Removed non-standard tags and misc javadoc cleanup

File Contents

# Content
1 /*
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 package java.util.concurrent;
8
9 /**
10 * 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 * various contexts.
17 *
18 * <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 *
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 * the following code will timeout in 50 milliseconds if the {@link java.util.concurrent.locks.Lock lock}
27 * 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 * <pre>
33 * 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 * @author Doug Lea
42 */
43 public final class TimeUnit implements java.io.Serializable {
44
45 /**
46 * Convert the given time duration in the given unit to the
47 * current unit. Conversions from finer to coarser granulaties
48 * truncate, so lose precision. Conversions from coarser to finer
49 * granularities with arguments that would numerically overflow
50 * saturate to <tt>Long.MIN_VALUE</tt> if negative or
51 * <tt>Long.MAX_VALUE</tt> if positive.
52 *
53 * @param duration the time duration in the given <tt>unit</tt>
54 * @param unit the unit of the <tt>duration</tt> argument
55 * @return the converted duration in the current unit,
56 * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
57 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
58 */
59 public long convert(long duration, TimeUnit unit) {
60 int i = unit.index - index;
61 if (i == 0)
62 return duration;
63 if (i < 0)
64 return duration / multipliers[-i];
65 if (duration > overflows[i])
66 return Long.MAX_VALUE;
67 if (duration < -overflows[i])
68 return Long.MIN_VALUE;
69 return duration * multipliers[i];
70 }
71
72 /**
73 * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
74 * @param duration the duration
75 * @return the converted duration.
76 * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
77 * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
78 **/
79 public long toNanos(long duration) {
80 if (index == NS)
81 return duration;
82 if (duration > overflows[index])
83 return Long.MAX_VALUE;
84 if (duration < -overflows[index])
85 return Long.MIN_VALUE;
86 return duration * multipliers[index];
87 }
88
89 /**
90 * Perform a timed <tt>Object.wait</tt> using the current time unit.
91 * This is a convenience method that converts timeout arguments into the
92 * form required by the <tt>Object.wait</tt> method.
93 * <p>For example, you could implement a blocking <tt>poll</tt> method (see
94 * {@link BlockingQueue#poll BlockingQueue.poll} using:
95 * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
96 * while (empty) {
97 * unit.timedWait(this, timeout);
98 * ...
99 * }
100 * }</pre>
101 * @param obj the object to wait on
102 * @param timeout the maximum time to wait.
103 * @throws InterruptedException if interrupted while waiting.
104 * @see Object#wait(long, int)
105 */
106 public void timedWait(Object obj, long timeout)
107 throws InterruptedException {
108 if (timeout > 0) {
109 long ms = MILLISECONDS.convert(timeout, this);
110 int ns = excessNanos(timeout, ms);
111 obj.wait(ms, ns);
112 }
113 }
114
115 /**
116 * Perform a timed <tt>Thread.join</tt> using the current time unit.
117 * This is a convenience method that converts time arguments into the
118 * form required by the <tt>Thread.join</tt> method.
119 * @param thread the thread to wait for
120 * @param timeout the maximum time to wait
121 * @throws InterruptedException if interrupted while waiting.
122 * @see Thread#join(long, int)
123 */
124 public void timedJoin(Thread thread, long timeout)
125 throws InterruptedException {
126 if (timeout > 0) {
127 long ms = MILLISECONDS.convert(timeout, this);
128 int ns = excessNanos(timeout, ms);
129 thread.join(ms, ns);
130 }
131 }
132
133 /**
134 * Perform a <tt>Thread.sleep</tt> using the current time unit.
135 * This is a convenience method that converts time arguments into the
136 * form required by the <tt>Thread.sleep</tt> method.
137 * @param timeout the minimum time to sleep
138 * @throws InterruptedException if interrupted while sleeping.
139 * @see Thread#sleep
140 */
141 public void sleep(long timeout) throws InterruptedException {
142 if (timeout > 0) {
143 long ms = MILLISECONDS.convert(timeout, this);
144 int ns = excessNanos(timeout, ms);
145 Thread.sleep(ms, ns);
146 }
147 }
148
149 /**
150 * Return the common name for this unit.
151 */
152 public String toString() {
153 return unitName;
154 }
155
156 private final String unitName;
157
158 /* ordered indices for each time unit */
159 private static final int NS = 0;
160 private static final int US = 1;
161 private static final int MS = 2;
162 private static final int S = 3;
163
164 /** quick lookup table for conversion factors */
165 static final int[] multipliers = { 1,
166 1000,
167 1000*1000,
168 1000*1000*1000 };
169
170 /** lookup table to check saturation */
171 static final long[] overflows = {
172 // Note that because we are dividing these down anyway,
173 // we don't have to deal with asymmetry of MIN/MAX values.
174 0, // unused
175 Long.MAX_VALUE / 1000,
176 Long.MAX_VALUE / (1000 * 1000),
177 Long.MAX_VALUE / (1000 * 1000 * 1000) };
178
179 /** the index of this unit */
180 int index;
181
182 /** private constructor */
183 TimeUnit(int index, String name) {
184 this.index = index;
185 this.unitName = name;
186 }
187
188 /**
189 * Utility method to compute the excess-nanosecond argument to
190 * wait, sleep, join. The results may overflow, so public methods
191 * invoking this should document possible overflow unless
192 * overflow is known not to be possible for the given arguments.
193 */
194 private int excessNanos(long time, long ms) {
195 if (index == NS)
196 return (int) (time - (ms * multipliers[MS-NS]));
197 else if (index == US)
198 return (int) ((time * multipliers[US-NS]) - (ms * multipliers[MS-NS]));
199 else
200 return 0;
201 }
202
203 /** Unit for one-second granularities. */
204 public static final TimeUnit SECONDS = new TimeUnit(S, "seconds");
205
206 /** Unit for one-millisecond granularities. */
207 public static final TimeUnit MILLISECONDS = new TimeUnit(MS, "milliseconds");
208
209 /** Unit for one-microsecond granularities. */
210 public static final TimeUnit MICROSECONDS = new TimeUnit(US, "microseconds");
211
212 /** Unit for one-nanosecond granularities. */
213 public static final TimeUnit NANOSECONDS = new TimeUnit(NS, "nanoseconds");
214
215 }