99 vclass, 100 fieldName); 101 } 102 103 /** 104 * Protected do-nothing constructor for use by subclasses. 105 */ 106 protected AtomicReferenceFieldUpdater() { 107 } 108 109 /** 110 * Atomically sets the field of the given object managed by this updater 111 * to the given updated value if the current value {@code ==} the 112 * expected value. This method is guaranteed to be atomic with respect to 113 * other calls to {@code compareAndSet} and {@code set}, but not 114 * necessarily with respect to other changes in the field. 115 * 116 * @param obj An object whose field to conditionally set 117 * @param expect the expected value 118 * @param update the new value 119 * @return true if successful. 120 */ 121 public abstract boolean compareAndSet(T obj, V expect, V update); 122 123 /** 124 * Atomically sets the field of the given object managed by this updater 125 * to the given updated value if the current value {@code ==} the 126 * expected value. This method is guaranteed to be atomic with respect to 127 * other calls to {@code compareAndSet} and {@code set}, but not 128 * necessarily with respect to other changes in the field. 129 * 130 * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> 131 * and does not provide ordering guarantees, so is only rarely an 132 * appropriate alternative to {@code compareAndSet}. 133 * 134 * @param obj An object whose field to conditionally set 135 * @param expect the expected value 136 * @param update the new value 137 * @return true if successful. 138 */ 139 public abstract boolean weakCompareAndSet(T obj, V expect, V update); 140 141 /** 142 * Sets the field of the given object managed by this updater to the 143 * given updated value. This operation is guaranteed to act as a volatile 144 * store with respect to subsequent invocations of {@code compareAndSet}. 145 * 146 * @param obj An object whose field to set 147 * @param newValue the new value 148 */ 149 public abstract void set(T obj, V newValue); 150 151 /** 152 * Eventually sets the field of the given object managed by this 153 * updater to the given updated value. 154 * 155 * @param obj An object whose field to set 156 * @param newValue the new value 157 * @since 1.6 159 public abstract void lazySet(T obj, V newValue); 160 161 /** 162 * Gets the current value held in the field of the given object managed 163 * by this updater. 164 * 165 * @param obj An object whose field to get 166 * @return the current value 167 */ 168 public abstract V get(T obj); 169 170 /** 171 * Atomically sets the field of the given object managed by this updater 172 * to the given value and returns the old value. 173 * 174 * @param obj An object whose field to get and set 175 * @param newValue the new value 176 * @return the previous value 177 */ 178 public V getAndSet(T obj, V newValue) { 179 for (;;) { 180 V current = get(obj); 181 if (compareAndSet(obj, current, newValue)) 182 return current; 183 } 184 } 185 186 private static final class AtomicReferenceFieldUpdaterImpl<T,V> 187 extends AtomicReferenceFieldUpdater<T,V> { 188 private static final Unsafe unsafe = Unsafe.getUnsafe(); 189 private final long offset; 190 private final Class<T> tclass; 191 private final Class<V> vclass; 192 private final Class<?> cclass; 193 194 /* 195 * Internal type checks within all update methods contain 196 * internal inlined optimizations checking for the common 197 * cases where the class is final (in which case a simple 198 * getClass comparison suffices) or is of type Object (in 199 * which case no check is needed because all objects are 200 * instances of Object). The Object case is handled simply by 201 * setting vclass to null in constructor. The targetCheck and 202 * updateCheck methods are invoked when these faster 203 * screenings fail. 204 */ 304 vclass != newValue.getClass())) 305 updateCheck(obj, newValue); 306 unsafe.putObjectVolatile(obj, offset, newValue); 307 } 308 309 public void lazySet(T obj, V newValue) { 310 if (obj == null || obj.getClass() != tclass || cclass != null || 311 (newValue != null && vclass != null && 312 vclass != newValue.getClass())) 313 updateCheck(obj, newValue); 314 unsafe.putOrderedObject(obj, offset, newValue); 315 } 316 317 @SuppressWarnings("unchecked") 318 public V get(T obj) { 319 if (obj == null || obj.getClass() != tclass || cclass != null) 320 targetCheck(obj); 321 return (V)unsafe.getObjectVolatile(obj, offset); 322 } 323 324 private void ensureProtectedAccess(T obj) { 325 if (cclass.isInstance(obj)) { 326 return; 327 } 328 throw new RuntimeException( 329 new IllegalAccessException("Class " + 330 cclass.getName() + 331 " can not access a protected member of class " + 332 tclass.getName() + 333 " using an instance of " + 334 obj.getClass().getName() 335 ) 336 ); 337 } 338 } 339 } | 99 vclass, 100 fieldName); 101 } 102 103 /** 104 * Protected do-nothing constructor for use by subclasses. 105 */ 106 protected AtomicReferenceFieldUpdater() { 107 } 108 109 /** 110 * Atomically sets the field of the given object managed by this updater 111 * to the given updated value if the current value {@code ==} the 112 * expected value. This method is guaranteed to be atomic with respect to 113 * other calls to {@code compareAndSet} and {@code set}, but not 114 * necessarily with respect to other changes in the field. 115 * 116 * @param obj An object whose field to conditionally set 117 * @param expect the expected value 118 * @param update the new value 119 * @return true if successful 120 */ 121 public abstract boolean compareAndSet(T obj, V expect, V update); 122 123 /** 124 * Atomically sets the field of the given object managed by this updater 125 * to the given updated value if the current value {@code ==} the 126 * expected value. This method is guaranteed to be atomic with respect to 127 * other calls to {@code compareAndSet} and {@code set}, but not 128 * necessarily with respect to other changes in the field. 129 * 130 * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> 131 * and does not provide ordering guarantees, so is only rarely an 132 * appropriate alternative to {@code compareAndSet}. 133 * 134 * @param obj An object whose field to conditionally set 135 * @param expect the expected value 136 * @param update the new value 137 * @return true if successful 138 */ 139 public abstract boolean weakCompareAndSet(T obj, V expect, V update); 140 141 /** 142 * Sets the field of the given object managed by this updater to the 143 * given updated value. This operation is guaranteed to act as a volatile 144 * store with respect to subsequent invocations of {@code compareAndSet}. 145 * 146 * @param obj An object whose field to set 147 * @param newValue the new value 148 */ 149 public abstract void set(T obj, V newValue); 150 151 /** 152 * Eventually sets the field of the given object managed by this 153 * updater to the given updated value. 154 * 155 * @param obj An object whose field to set 156 * @param newValue the new value 157 * @since 1.6 159 public abstract void lazySet(T obj, V newValue); 160 161 /** 162 * Gets the current value held in the field of the given object managed 163 * by this updater. 164 * 165 * @param obj An object whose field to get 166 * @return the current value 167 */ 168 public abstract V get(T obj); 169 170 /** 171 * Atomically sets the field of the given object managed by this updater 172 * to the given value and returns the old value. 173 * 174 * @param obj An object whose field to get and set 175 * @param newValue the new value 176 * @return the previous value 177 */ 178 public V getAndSet(T obj, V newValue) { 179 V prev; 180 do { 181 prev = get(obj); 182 } while (!compareAndSet(obj, prev, newValue)); 183 return prev; 184 } 185 186 private static final class AtomicReferenceFieldUpdaterImpl<T,V> 187 extends AtomicReferenceFieldUpdater<T,V> { 188 private static final Unsafe unsafe = Unsafe.getUnsafe(); 189 private final long offset; 190 private final Class<T> tclass; 191 private final Class<V> vclass; 192 private final Class<?> cclass; 193 194 /* 195 * Internal type checks within all update methods contain 196 * internal inlined optimizations checking for the common 197 * cases where the class is final (in which case a simple 198 * getClass comparison suffices) or is of type Object (in 199 * which case no check is needed because all objects are 200 * instances of Object). The Object case is handled simply by 201 * setting vclass to null in constructor. The targetCheck and 202 * updateCheck methods are invoked when these faster 203 * screenings fail. 204 */ 304 vclass != newValue.getClass())) 305 updateCheck(obj, newValue); 306 unsafe.putObjectVolatile(obj, offset, newValue); 307 } 308 309 public void lazySet(T obj, V newValue) { 310 if (obj == null || obj.getClass() != tclass || cclass != null || 311 (newValue != null && vclass != null && 312 vclass != newValue.getClass())) 313 updateCheck(obj, newValue); 314 unsafe.putOrderedObject(obj, offset, newValue); 315 } 316 317 @SuppressWarnings("unchecked") 318 public V get(T obj) { 319 if (obj == null || obj.getClass() != tclass || cclass != null) 320 targetCheck(obj); 321 return (V)unsafe.getObjectVolatile(obj, offset); 322 } 323 324 @SuppressWarnings("unchecked") 325 public V getAndSet(T obj, V newValue) { 326 if (obj == null || obj.getClass() != tclass || cclass != null || 327 (newValue != null && vclass != null && 328 vclass != newValue.getClass())) 329 updateCheck(obj, newValue); 330 return (V)unsafe.getAndSetObject(obj, offset, newValue); 331 } 332 333 private void ensureProtectedAccess(T obj) { 334 if (cclass.isInstance(obj)) { 335 return; 336 } 337 throw new RuntimeException( 338 new IllegalAccessException("Class " + 339 cclass.getName() + 340 " can not access a protected member of class " + 341 tclass.getName() + 342 " using an instance of " + 343 obj.getClass().getName() 344 ) 345 ); 346 } 347 } 348 } |