1 7 8 package java.util.concurrent.atomic; 9 import sun.misc.Unsafe; 10 import java.lang.reflect.*; 11 12 48 public abstract class AtomicReferenceFieldUpdater<T, V> { 49 50 62 public static <U, W> AtomicReferenceFieldUpdater <U,W> newUpdater(Class <U> tclass, Class <W> vclass, String fieldName) { 63 return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, 65 vclass, 66 fieldName); 67 } 68 69 72 protected AtomicReferenceFieldUpdater() { 73 } 74 75 87 88 public abstract boolean compareAndSet(T obj, V expect, V update); 89 90 102 public abstract boolean weakCompareAndSet(T obj, V expect, V update); 103 104 111 public abstract void set(T obj, V newValue); 112 113 118 public abstract V get(T obj); 119 120 127 public V getAndSet(T obj, V newValue) { 128 for (;;) { 129 V current = get(obj); 130 if (compareAndSet(obj, current, newValue)) 131 return current; 132 } 133 } 134 135 138 private static class AtomicReferenceFieldUpdaterImpl<T,V> extends AtomicReferenceFieldUpdater <T,V> { 139 private static final Unsafe unsafe = Unsafe.getUnsafe(); 140 private final long offset; 141 private final Class <T> tclass; 142 private final Class <V> vclass; 143 private final Class cclass; 144 145 AtomicReferenceFieldUpdaterImpl(Class <T> tclass, Class <V> vclass, String fieldName) { 146 Field field = null; 147 Class fieldClass = null; 148 Class caller = null; 149 int modifiers = 0; 150 try { 151 field = tclass.getDeclaredField(fieldName); 152 caller = sun.reflect.Reflection.getCallerClass(3); 153 modifiers = field.getModifiers(); 154 sun.reflect.misc.ReflectUtil.ensureMemberAccess( 155 caller, tclass, null, modifiers); 156 sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 157 fieldClass = field.getType(); 158 } catch(Exception ex) { 159 throw new RuntimeException (ex); 160 } 161 162 if (vclass != fieldClass) 163 throw new ClassCastException (); 164 165 if (!Modifier.isVolatile(modifiers)) 166 throw new IllegalArgumentException ("Must be volatile type"); 167 168 this.cclass = (Modifier.isProtected(modifiers) && 169 caller != tclass) ? caller : null; 170 this.tclass = tclass; 171 this.vclass = vclass; 172 offset = unsafe.objectFieldOffset(field); 173 } 174 175 176 public boolean compareAndSet(T obj, V expect, V update) { 177 if (!tclass.isInstance(obj) || 178 (update != null && !vclass.isInstance(update))) 179 throw new ClassCastException (); 180 if (cclass != null) 181 ensureProtectedAccess(obj); 182 return unsafe.compareAndSwapObject(obj, offset, expect, update); 183 } 184 185 public boolean weakCompareAndSet(T obj, V expect, V update) { 186 if (!tclass.isInstance(obj) || 188 (update != null && !vclass.isInstance(update))) 189 throw new ClassCastException (); 190 if (cclass != null) 191 ensureProtectedAccess(obj); 192 return unsafe.compareAndSwapObject(obj, offset, expect, update); 193 } 194 195 196 public void set(T obj, V newValue) { 197 if (!tclass.isInstance(obj) || 198 (newValue != null && !vclass.isInstance(newValue))) 199 throw new ClassCastException (); 200 if (cclass != null) 201 ensureProtectedAccess(obj); 202 unsafe.putObjectVolatile(obj, offset, newValue); 203 } 204 205 public V get(T obj) { 206 if (!tclass.isInstance(obj)) 207 throw new ClassCastException (); 208 if (cclass != null) 209 ensureProtectedAccess(obj); 210 return (V)unsafe.getObjectVolatile(obj, offset); 211 } 212 213 private void ensureProtectedAccess(T obj) { 214 if (cclass.isInstance(obj)) { 215 return; 216 } 217 throw new RuntimeException ( 218 new IllegalAccessException ("Class " + 219 cclass.getName() + 220 " can not access a protected member of class " + 221 tclass.getName() + 222 " using an instance of " + 223 obj.getClass().getName() 224 ) 225 ); 226 } 227 } 228 } 229 230 | Popular Tags |