ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongMaxUpdater.java
Revision: 1.11
Committed: Mon May 5 20:20:15 2014 UTC (9 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +7 -4 lines
Log Message:
import everything to reduce diffs with guava fork

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