ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongMaxUpdater.java
Revision: 1.4
Committed: Sun Nov 18 03:07:22 2012 UTC (11 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
properly close <em> javadoc tags

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