ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleMaxUpdater.java
Revision: 1.9
Committed: Mon Jan 14 02:02:41 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +1 -1 lines
Log Message:
punctuation

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