ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleMaxUpdater.java
Revision: 1.7
Committed: Sun Jan 6 18:50:00 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +1 -1 lines
Log Message:
javadoc style

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, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package jsr166e;
8 import java.io.IOException;
9 import java.io.Serializable;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12
13 /**
14 * One or more variables that together maintain a running {@code double}
15 * maximum with initial value {@code Double.NEGATIVE_INFINITY}. When
16 * updates (method {@link #update}) are contended across threads, the
17 * set of variables may grow dynamically to reduce contention. Method
18 * {@link #max} (or, equivalently, {@link #doubleValue}) returns the
19 * current maximum across the variables maintaining updates.
20 *
21 * <p>This class extends {@link Number}, but does <em>not</em> define
22 * methods such as {@code equals}, {@code hashCode} and {@code
23 * compareTo} because instances are expected to be mutated, and so are
24 * not useful as collection keys.
25 *
26 * <p><em>jsr166e note: This class is targeted to be placed in
27 * java.util.concurrent.atomic.</em>
28 *
29 * @since 1.8
30 * @author Doug Lea
31 */
32 public class DoubleMaxUpdater extends Striped64 implements Serializable {
33 private static final long serialVersionUID = 7249069246863182397L;
34 /**
35 * Long representation of negative infinity. See class Double
36 * internal documentation for explanation.
37 */
38 private static final long MIN_AS_LONG = 0xfff0000000000000L;
39
40 /**
41 * Update function. See class DoubleAdder for rationale
42 * for using conversions from/to long.
43 */
44 final long fn(long v, long x) {
45 return Double.longBitsToDouble(v) > Double.longBitsToDouble(x) ? v : x;
46 }
47
48 /**
49 * Creates a new instance with initial value of {@code
50 * Double.NEGATIVE_INFINITY}.
51 */
52 public DoubleMaxUpdater() {
53 base = MIN_AS_LONG;
54 }
55
56 /**
57 * Updates the maximum to be at least the given value.
58 *
59 * @param x the value to update
60 */
61 public void update(double x) {
62 long lx = Double.doubleToRawLongBits(x);
63 Cell[] as; long b, v; HashCode hc; Cell a; int n;
64 if ((as = cells) != null ||
65 (Double.longBitsToDouble(b = base) < x && !casBase(b, lx))) {
66 boolean uncontended = true;
67 int h = (hc = threadHashCode.get()).code;
68 if (as == null || (n = as.length) < 1 ||
69 (a = as[(n - 1) & h]) == null ||
70 (Double.longBitsToDouble(v = a.value) < x &&
71 !(uncontended = a.cas(v, lx))))
72 retryUpdate(lx, hc, uncontended);
73 }
74 }
75
76 /**
77 * Returns the current maximum. The returned value is
78 * <em>NOT</em> an atomic snapshot: invocation in the absence of
79 * concurrent updates returns an accurate result, but concurrent
80 * updates that occur while the value is being calculated might
81 * not be incorporated.
82 *
83 * @return the maximum
84 */
85 public double max() {
86 Cell[] as = cells;
87 double max = Double.longBitsToDouble(base);
88 if (as != null) {
89 int n = as.length;
90 double v;
91 for (int i = 0; i < n; ++i) {
92 Cell a = as[i];
93 if (a != null && (v = Double.longBitsToDouble(a.value)) > max)
94 max = v;
95 }
96 }
97 return max;
98 }
99
100 /**
101 * Resets variables maintaining updates to {@code
102 * Double.NEGATIVE_INFINITY}. This method may be a useful
103 * alternative to creating a new updater, but is only effective if
104 * there are no concurrent updates. Because this method is
105 * intrinsically racy, it should only be used when it is known
106 * that no threads are concurrently updating.
107 */
108 public void reset() {
109 internalReset(MIN_AS_LONG);
110 }
111
112 /**
113 * Equivalent in effect to {@link #max} followed by {@link
114 * #reset}. This method may apply for example during quiescent
115 * points between multithreaded computations. If there are
116 * updates concurrent with this method, the returned value is
117 * <em>not</em> guaranteed to be the final value occurring before
118 * the reset.
119 *
120 * @return the maximum
121 */
122 public double maxThenReset() {
123 Cell[] as = cells;
124 double max = Double.longBitsToDouble(base);
125 base = MIN_AS_LONG;
126 if (as != null) {
127 int n = as.length;
128 for (int i = 0; i < n; ++i) {
129 Cell a = as[i];
130 if (a != null) {
131 double v = Double.longBitsToDouble(a.value);
132 a.value = MIN_AS_LONG;
133 if (v > max)
134 max = v;
135 }
136 }
137 }
138 return max;
139 }
140
141 /**
142 * Returns the String representation of the {@link #max}.
143 * @return the String representation of the {@link #max}
144 */
145 public String toString() {
146 return Double.toString(max());
147 }
148
149 /**
150 * Equivalent to {@link #max}.
151 *
152 * @return the max
153 */
154 public double doubleValue() {
155 return max();
156 }
157
158 /**
159 * Returns the {@link #max} as a {@code long} after a
160 * narrowing primitive conversion.
161 */
162 public long longValue() {
163 return (long)max();
164 }
165
166 /**
167 * Returns the {@link #max} as an {@code int} after a
168 * narrowing primitive conversion.
169 */
170 public int intValue() {
171 return (int)max();
172 }
173
174 /**
175 * Returns the {@link #max} as a {@code float}
176 * after a narrowing primitive conversion.
177 */
178 public float floatValue() {
179 return (float)max();
180 }
181
182 private void writeObject(java.io.ObjectOutputStream s)
183 throws java.io.IOException {
184 s.defaultWriteObject();
185 s.writeDouble(max());
186 }
187
188 private void readObject(ObjectInputStream s)
189 throws IOException, ClassNotFoundException {
190 s.defaultReadObject();
191 busy = 0;
192 cells = null;
193 base = Double.doubleToRawLongBits(s.readDouble());
194 }
195
196 }