ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/TimeUnit.java
Revision: 1.1
Committed: Wed May 14 21:30:48 2003 UTC (21 years, 1 month ago) by tim
Branch: MAIN
Log Message:
Moved main source rooted at . to ./src/main
Moved test source rooted at ./etc/testcases to ./src/test

File Contents

# Content
1 package java.util.concurrent;
2
3 /**
4 * A <tt>TimeUnit</tt> represents time durations at a given unit of
5 * granularity and provides utility methods to convert across units,
6 * and to perform timing and delay operations in these units.
7 * <tt>TimeUnit</tt> is a &quot;featherweight&quot; class.
8 * It does not maintain time information, but only helps organize and
9 * use time representations that may be maintained separately across
10 * various contexts.
11 * A static method {@link #highResolutionTime} provides access to a high
12 * resolution, nanosecond, timer, which can be used to measure elapsed time.
13 *
14 * <p>The <tt>TimeUnit</tt> class cannot be directly instantiated.
15 * Use the {@link #SECONDS}, {@link #MILLISECONDS}, {@link #MICROSECONDS},
16 * and {@link #NANOSECONDS} static instances that provide predefined
17 * units of precision. If you use these frequently, consider
18 * statically importing this class.
19 *
20 * <p>A <tt>TimeUnit</tt> is mainly used to inform blocking methods which
21 * can timeout, how the timeout parameter should be interpreted. For example,
22 * the following code will timeout in 50 milliseconds if the {@link Lock lock}
23 * is not available:
24 * <pre> Lock lock = ...;
25 * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
26 * </pre>
27 * while this code will timeout in 50 seconds:
28 * <pre>
29 * Lock lock = ...;
30 * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
31 * </pre>
32 * Note however, that there is no guarantee that a particular lock, in this
33 * case, will be able to notice the passage of time at the same granularity
34 * as the given <tt>TimeUnit</tt>.
35 *
36 * @since 1.5
37 * @spec JSR-166
38 * @revised $Date: 2003/03/29 02:17:05 $
39 * @editor $Author: dholmes $
40 *
41 * @fixme The previous version created singleton subclass instances. I could
42 * not see any reason to create subclasses instead of just instances.
43 * Neither approach allows creation of your own units.
44 */
45 public final class TimeUnit implements java.io.Serializable {
46
47 /**
48 * Return the current value of the system high resolution timer, in
49 * nanoseconds. This method can only be used to measure elapsed time
50 * and is not related to any notion of system, or wall-clock time.
51 * Although the value returned represents nanoseconds since some
52 * arbitrary start time in the past, the resolution at which this value
53 * is updated is not specified. So we have nanosecond precision, but
54 * not necessarily nanosecond accuracy.
55 * It is guaranteed that successive return
56 * values from this method will not decrease.
57 *
58 * <p> For example to measure how long some code takes to execute,
59 * with nanosecond precision:
60 * <pre>
61 * long startTime = TimeUnit.highResolutionTime();
62 * // ... the code being measured ...
63 * long estimatedTime = TimeUnit.highResolutionTime() - startTime;
64 * </pre>
65 *
66 * @return The current value of the system high resolution timer, in
67 * nanoseconds.
68 *
69 * @fixme Is this spec tight enough? Too tight? What about issues of
70 * reading the TSC from different processors on a SMP?
71 */
72 public static final long highResolutionTime() {
73 return systemTimeNanos();
74 }
75
76 /**
77 * Convert the given time duration in the given unit to the
78 * current unit. Conversions from finer to coarser granulaties
79 * truncate, so lose precision. Conversions from coarser to finer
80 * granularities may numerically overflow.
81 *
82 * @param duration the time duration in the given <tt>unit</tt>
83 * @param unit the unit of the <tt>duration</tt> argument
84 * @return the converted duration in the current unit.
85 */
86 public long convert(long duration, TimeUnit unit) {
87 if (index > unit.index) {
88 return duration / multipliers[index - unit.index];
89 }
90 else {
91 return duration * multipliers[unit.index - index];
92 }
93 }
94
95 /**
96 * Perform a timed <tt>Object.wait</tt> using the current time unit.
97 * This is a convenience method that converts timeout arguments into the
98 * form required by the <tt>Object.wait</tt> method.
99 * <p>For example, you could implement a blocking <tt>poll</tt> method (see
100 * {@link BlockingQueue#poll BlockingQueue.poll} using:
101 * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
102 * while (empty) {
103 * unit.timedWait(this, timeout);
104 * ...
105 * }
106 * }</pre>
107 * @param obj the object to wait on
108 * @param timeout the maximum time to wait
109 * @throws InterruptedException if interrupted while waiting.
110 * @see Object#wait(long, int)
111 */
112 public void timedWait(Object obj, long timeout)
113 throws InterruptedException {
114 long ms = MILLISECONDS.convert(timeout, this);
115 int ns = excessNanos(timeout, ms);
116 obj.wait(ms, ns);
117 }
118
119 /**
120 * Perform a timed <tt>Thread.join</tt> using the current time unit.
121 * This is a convenience method that converts time arguments into the
122 * form required by the <tt>Thread.join</tt> method.
123 * @param thread the thread to wait for
124 * @param timeout the maximum time to wait
125 * @throws InterruptedException if interrupted while waiting.
126 * @see Thread#join(long, int)
127 */
128 public void timedJoin(Thread thread, long timeout)
129 throws InterruptedException {
130 long ms = MILLISECONDS.convert(timeout, this);
131 int ns = excessNanos(timeout, ms);
132 thread.join(ms, ns);
133 }
134
135 /**
136 * Perform a <tt>Thread.sleep</tt> using the current time unit.
137 * This is a convenience method that converts time arguments into the
138 * form required by the <tt>Thread.sleep</tt> method.
139 * @param time the minimum time to sleep
140 * @throws InterruptedException if interrupted while sleeping.
141 * @see Thread#sleep
142 */
143 public void sleep(long timeout) throws InterruptedException {
144 long ms = MILLISECONDS.convert(timeout, this);
145 int ns = excessNanos(timeout, ms);
146 Thread.sleep(ms, ns);
147 }
148
149 /* ordered indices for each time unit */
150 private static final int NS = 0;
151 private static final int US = 1;
152 private static final int MS = 2;
153 private static final int S = 3;
154
155 /* quick lookup table for conversion factors */
156 static final int[] multipliers = { 1, 1000, 1000*1000, 1000*1000*1000 };
157
158 /* the index of this unit */
159 int index;
160
161 /** private constructor */
162 TimeUnit(int index) { this.index = index; }
163
164 /**
165 * Utility method to compute the excess-nanosecond argument to
166 * wait, sleep, join.
167 * @fixme overflow?
168 */
169 private int excessNanos(long time, long ms) {
170 if (index == NS)
171 return (int) (time - (ms * multipliers[MS-NS]));
172 else if (index == US)
173 return (int) ((time * multipliers[US-NS]) - (ms * multipliers[MS-NS]));
174 else
175 return 0;
176 }
177
178 /** Underlying native time call */
179 static native long systemTimeNanos();
180
181 /** Unit for one-second granularities */
182 public static final TimeUnit SECONDS = new TimeUnit(S);
183
184 /** Unit for one-millisecond granularities */
185 public static final TimeUnit MILLISECONDS = new TimeUnit(MS);
186
187 /** Unit for one-microsecond granularities */
188 public static final TimeUnit MICROSECONDS = new TimeUnit(US);
189
190 /** Unit for one-nanosecond granularities */
191 public static final TimeUnit NANOSECONDS = new TimeUnit(NS);
192
193 }