1 7 8 package java.util.concurrent.atomic; 9 import sun.misc.Unsafe; 10 import java.lang.reflect.*; 11 12 29 public abstract class AtomicIntegerFieldUpdater<T> { 30 42 public static <U> AtomicIntegerFieldUpdater <U> newUpdater(Class <U> tclass, String fieldName) { 43 return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName); 44 } 45 46 49 protected AtomicIntegerFieldUpdater() { 50 } 51 52 66 67 public abstract boolean compareAndSet(T obj, int expect, int update); 68 69 83 84 public abstract boolean weakCompareAndSet(T obj, int expect, int update); 85 86 93 public abstract void set(T obj, int newValue); 94 95 100 public abstract int get(T obj); 101 102 109 public int getAndSet(T obj, int newValue) { 110 for (;;) { 111 int current = get(obj); 112 if (compareAndSet(obj, current, newValue)) 113 return current; 114 } 115 } 116 117 122 public int getAndIncrement(T obj) { 123 for (;;) { 124 int current = get(obj); 125 int next = current + 1; 126 if (compareAndSet(obj, current, next)) 127 return current; 128 } 129 } 130 131 132 137 public int getAndDecrement(T obj) { 138 for (;;) { 139 int current = get(obj); 140 int next = current - 1; 141 if (compareAndSet(obj, current, next)) 142 return current; 143 } 144 } 145 146 147 153 public int getAndAdd(T obj, int delta) { 154 for (;;) { 155 int current = get(obj); 156 int next = current + delta; 157 if (compareAndSet(obj, current, next)) 158 return current; 159 } 160 } 161 162 167 public int incrementAndGet(T obj) { 168 for (;;) { 169 int current = get(obj); 170 int next = current + 1; 171 if (compareAndSet(obj, current, next)) 172 return next; 173 } 174 } 175 176 177 182 public int decrementAndGet(T obj) { 183 for (;;) { 184 int current = get(obj); 185 int next = current - 1; 186 if (compareAndSet(obj, current, next)) 187 return next; 188 } 189 } 190 191 192 198 public int addAndGet(T obj, int delta) { 199 for (;;) { 200 int current = get(obj); 201 int next = current + delta; 202 if (compareAndSet(obj, current, next)) 203 return next; 204 } 205 } 206 207 210 private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater <T> { 211 private static final Unsafe unsafe = Unsafe.getUnsafe(); 212 private final long offset; 213 private final Class <T> tclass; 214 private final Class cclass; 215 216 AtomicIntegerFieldUpdaterImpl(Class <T> tclass, String fieldName) { 217 Field field = null; 218 Class caller = null; 219 int modifiers = 0; 220 try { 221 field = tclass.getDeclaredField(fieldName); 222 caller = sun.reflect.Reflection.getCallerClass(3); 223 modifiers = field.getModifiers(); 224 sun.reflect.misc.ReflectUtil.ensureMemberAccess( 225 caller, tclass, null, modifiers); 226 sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 227 } catch(Exception ex) { 228 throw new RuntimeException (ex); 229 } 230 231 Class fieldt = field.getType(); 232 if (fieldt != int.class) 233 throw new IllegalArgumentException ("Must be integer type"); 234 235 if (!Modifier.isVolatile(modifiers)) 236 throw new IllegalArgumentException ("Must be volatile type"); 237 238 this.cclass = (Modifier.isProtected(modifiers) && 239 caller != tclass) ? caller : null; 240 this.tclass = tclass; 241 offset = unsafe.objectFieldOffset(field); 242 } 243 244 public boolean compareAndSet(T obj, int expect, int update) { 245 if (!tclass.isInstance(obj)) 246 throw new ClassCastException (); 247 if (cclass != null) 248 ensureProtectedAccess(obj); 249 return unsafe.compareAndSwapInt(obj, offset, expect, update); 250 } 251 252 public boolean weakCompareAndSet(T obj, int expect, int update) { 253 if (!tclass.isInstance(obj)) 254 throw new ClassCastException (); 255 if (cclass != null) 256 ensureProtectedAccess(obj); 257 return unsafe.compareAndSwapInt(obj, offset, expect, update); 258 } 259 260 public void set(T obj, int newValue) { 261 if (!tclass.isInstance(obj)) 262 throw new ClassCastException (); 263 if (cclass != null) 264 ensureProtectedAccess(obj); 265 unsafe.putIntVolatile(obj, offset, newValue); 266 } 267 268 public final int get(T obj) { 269 if (!tclass.isInstance(obj)) 270 throw new ClassCastException (); 271 if (cclass != null) 272 ensureProtectedAccess(obj); 273 return unsafe.getIntVolatile(obj, offset); 274 } 275 276 private void ensureProtectedAccess(T obj) { 277 if (cclass.isInstance(obj)) { 278 return; 279 } 280 throw new RuntimeException ( 281 new IllegalAccessException ("Class " + 282 cclass.getName() + 283 " can not access a protected member of class " + 284 tclass.getName() + 285 " using an instance of " + 286 obj.getClass().getName() 287 ) 288 ); 289 } 290 } 291 } 292 293 | Popular Tags |