96 * necessarily with respect to other changes in the field. |
96 * necessarily with respect to other changes in the field. |
97 * |
97 * |
98 * @param obj An object whose field to conditionally set |
98 * @param obj An object whose field to conditionally set |
99 * @param expect the expected value |
99 * @param expect the expected value |
100 * @param update the new value |
100 * @param update the new value |
101 * @return true if successful. |
101 * @return true if successful |
102 * @throws ClassCastException if {@code obj} is not an instance |
102 * @throws ClassCastException if {@code obj} is not an instance |
103 * of the class possessing the field established in the constructor. |
103 * of the class possessing the field established in the constructor. |
104 */ |
104 */ |
105 public abstract boolean compareAndSet(T obj, long expect, long update); |
105 public abstract boolean compareAndSet(T obj, long expect, long update); |
106 |
106 |
116 * appropriate alternative to {@code compareAndSet}. |
116 * appropriate alternative to {@code compareAndSet}. |
117 * |
117 * |
118 * @param obj An object whose field to conditionally set |
118 * @param obj An object whose field to conditionally set |
119 * @param expect the expected value |
119 * @param expect the expected value |
120 * @param update the new value |
120 * @param update the new value |
121 * @return true if successful. |
121 * @return true if successful |
122 * @throws ClassCastException if {@code obj} is not an instance |
122 * @throws ClassCastException if {@code obj} is not an instance |
123 * of the class possessing the field established in the constructor. |
123 * of the class possessing the field established in the constructor. |
124 */ |
124 */ |
125 public abstract boolean weakCompareAndSet(T obj, long expect, long update); |
125 public abstract boolean weakCompareAndSet(T obj, long expect, long update); |
126 |
126 |
160 * @param obj An object whose field to get and set |
160 * @param obj An object whose field to get and set |
161 * @param newValue the new value |
161 * @param newValue the new value |
162 * @return the previous value |
162 * @return the previous value |
163 */ |
163 */ |
164 public long getAndSet(T obj, long newValue) { |
164 public long getAndSet(T obj, long newValue) { |
165 for (;;) { |
165 long prev; |
166 long current = get(obj); |
166 do { |
167 if (compareAndSet(obj, current, newValue)) |
167 prev = get(obj); |
168 return current; |
168 } while (!compareAndSet(obj, prev, newValue)); |
169 } |
169 return prev; |
170 } |
170 } |
171 |
171 |
172 /** |
172 /** |
173 * Atomically increments by one the current value of the field of the |
173 * Atomically increments by one the current value of the field of the |
174 * given object managed by this updater. |
174 * given object managed by this updater. |
175 * |
175 * |
176 * @param obj An object whose field to get and set |
176 * @param obj An object whose field to get and set |
177 * @return the previous value |
177 * @return the previous value |
178 */ |
178 */ |
179 public long getAndIncrement(T obj) { |
179 public long getAndIncrement(T obj) { |
180 for (;;) { |
180 long prev, next; |
181 long current = get(obj); |
181 do { |
182 long next = current + 1; |
182 prev = get(obj); |
183 if (compareAndSet(obj, current, next)) |
183 next = prev + 1; |
184 return current; |
184 } while (!compareAndSet(obj, prev, next)); |
185 } |
185 return prev; |
186 } |
186 } |
187 |
187 |
188 /** |
188 /** |
189 * Atomically decrements by one the current value of the field of the |
189 * Atomically decrements by one the current value of the field of the |
190 * given object managed by this updater. |
190 * given object managed by this updater. |
191 * |
191 * |
192 * @param obj An object whose field to get and set |
192 * @param obj An object whose field to get and set |
193 * @return the previous value |
193 * @return the previous value |
194 */ |
194 */ |
195 public long getAndDecrement(T obj) { |
195 public long getAndDecrement(T obj) { |
196 for (;;) { |
196 long prev, next; |
197 long current = get(obj); |
197 do { |
198 long next = current - 1; |
198 prev = get(obj); |
199 if (compareAndSet(obj, current, next)) |
199 next = prev - 1; |
200 return current; |
200 } while (!compareAndSet(obj, prev, next)); |
201 } |
201 return prev; |
202 } |
202 } |
203 |
203 |
204 /** |
204 /** |
205 * Atomically adds the given value to the current value of the field of |
205 * Atomically adds the given value to the current value of the field of |
206 * the given object managed by this updater. |
206 * the given object managed by this updater. |
208 * @param obj An object whose field to get and set |
208 * @param obj An object whose field to get and set |
209 * @param delta the value to add |
209 * @param delta the value to add |
210 * @return the previous value |
210 * @return the previous value |
211 */ |
211 */ |
212 public long getAndAdd(T obj, long delta) { |
212 public long getAndAdd(T obj, long delta) { |
213 for (;;) { |
213 long prev, next; |
214 long current = get(obj); |
214 do { |
215 long next = current + delta; |
215 prev = get(obj); |
216 if (compareAndSet(obj, current, next)) |
216 next = prev + delta; |
217 return current; |
217 } while (!compareAndSet(obj, prev, next)); |
218 } |
218 return prev; |
219 } |
219 } |
220 |
220 |
221 /** |
221 /** |
222 * Atomically increments by one the current value of the field of the |
222 * Atomically increments by one the current value of the field of the |
223 * given object managed by this updater. |
223 * given object managed by this updater. |
224 * |
224 * |
225 * @param obj An object whose field to get and set |
225 * @param obj An object whose field to get and set |
226 * @return the updated value |
226 * @return the updated value |
227 */ |
227 */ |
228 public long incrementAndGet(T obj) { |
228 public long incrementAndGet(T obj) { |
229 for (;;) { |
229 long prev, next; |
230 long current = get(obj); |
230 do { |
231 long next = current + 1; |
231 prev = get(obj); |
232 if (compareAndSet(obj, current, next)) |
232 next = prev + 1; |
233 return next; |
233 } while (!compareAndSet(obj, prev, next)); |
234 } |
234 return next; |
235 } |
235 } |
236 |
236 |
237 /** |
237 /** |
238 * Atomically decrements by one the current value of the field of the |
238 * Atomically decrements by one the current value of the field of the |
239 * given object managed by this updater. |
239 * given object managed by this updater. |
240 * |
240 * |
241 * @param obj An object whose field to get and set |
241 * @param obj An object whose field to get and set |
242 * @return the updated value |
242 * @return the updated value |
243 */ |
243 */ |
244 public long decrementAndGet(T obj) { |
244 public long decrementAndGet(T obj) { |
245 for (;;) { |
245 long prev, next; |
246 long current = get(obj); |
246 do { |
247 long next = current - 1; |
247 prev = get(obj); |
248 if (compareAndSet(obj, current, next)) |
248 next = prev - 1; |
249 return next; |
249 } while (!compareAndSet(obj, prev, next)); |
250 } |
250 return next; |
251 } |
251 } |
252 |
252 |
253 /** |
253 /** |
254 * Atomically adds the given value to the current value of the field of |
254 * Atomically adds the given value to the current value of the field of |
255 * the given object managed by this updater. |
255 * the given object managed by this updater. |
257 * @param obj An object whose field to get and set |
257 * @param obj An object whose field to get and set |
258 * @param delta the value to add |
258 * @param delta the value to add |
259 * @return the updated value |
259 * @return the updated value |
260 */ |
260 */ |
261 public long addAndGet(T obj, long delta) { |
261 public long addAndGet(T obj, long delta) { |
262 for (;;) { |
262 long prev, next; |
263 long current = get(obj); |
263 do { |
264 long next = current + delta; |
264 prev = get(obj); |
265 if (compareAndSet(obj, current, next)) |
265 next = prev + delta; |
266 return next; |
266 } while (!compareAndSet(obj, prev, next)); |
267 } |
267 return next; |
268 } |
268 } |
269 |
269 |
270 private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { |
270 private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { |
271 private static final Unsafe unsafe = Unsafe.getUnsafe(); |
271 private static final Unsafe unsafe = Unsafe.getUnsafe(); |
272 private final long offset; |
272 private final long offset; |
343 public long get(T obj) { |
343 public long get(T obj) { |
344 if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); |
344 if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); |
345 return unsafe.getLongVolatile(obj, offset); |
345 return unsafe.getLongVolatile(obj, offset); |
346 } |
346 } |
347 |
347 |
|
348 public long getAndSet(T obj, long newValue) { |
|
349 if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); |
|
350 return unsafe.getAndSetLong(obj, offset, newValue); |
|
351 } |
|
352 |
|
353 public long getAndIncrement(T obj) { |
|
354 return getAndAdd(obj, 1); |
|
355 } |
|
356 |
|
357 public long getAndDecrement(T obj) { |
|
358 return getAndAdd(obj, -1); |
|
359 } |
|
360 |
|
361 public long getAndAdd(T obj, long delta) { |
|
362 if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); |
|
363 return unsafe.getAndAddLong(obj, offset, delta); |
|
364 } |
|
365 |
|
366 public long incrementAndGet(T obj) { |
|
367 return getAndAdd(obj, 1) + 1; |
|
368 } |
|
369 |
|
370 public long decrementAndGet(T obj) { |
|
371 return getAndAdd(obj, -1) - 1; |
|
372 } |
|
373 |
|
374 public long addAndGet(T obj, long delta) { |
|
375 return getAndAdd(obj, delta) + delta; |
|
376 } |
|
377 |
348 private void ensureProtectedAccess(T obj) { |
378 private void ensureProtectedAccess(T obj) { |
349 if (cclass.isInstance(obj)) { |
379 if (cclass.isInstance(obj)) { |
350 return; |
380 return; |
351 } |
381 } |
352 throw new RuntimeException( |
382 throw new RuntimeException( |