ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleMaxUpdater.java
Revision: 1.2
Committed: Sat Sep 10 01:38:28 2011 UTC (12 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +1 -0 lines
Log Message:
fix up @since

File Contents

# User Rev Content
1 dl 1.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 hashCode} and {@code compareTo} because
23     * instances are expected to be mutated, and so are not useful as
24     * collection keys.
25     *
26     * <p><em>jsr166e note: This class is targeted to be placed in
27     * java.util.concurrent.atomic<em>
28     *
29 jsr166 1.2 * @since 1.8
30 dl 1.1 * @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     * 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     * 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 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     }