下面列出了java.util.concurrent.atomic.AtomicReferenceFieldUpdater#newUpdater() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
@Tag("PASSING")
@Order(2)
public void compareAndSetUsingAtomicReferenceFieldUpdater() {
final AtomicReferenceFieldUpdater<TestSolutionCompareAndSet, Integer> valueUpdater =
AtomicReferenceFieldUpdater.newUpdater(TestSolutionCompareAndSet.class,
Integer.class,
"privateVolatile");
boolean exchanged = valueUpdater.compareAndSet(this, currentValue, newValue);
assertTrue(exchanged,
"The value should have been changed to 7, " +
"hence exchanged should be true"
);
assertEquals(newValue,
valueUpdater.get(this),
"The value of the privateVolatile should now be 7");
exchanged = valueUpdater.compareAndSet(this, 2, 33);
assertFalse(exchanged,
"The value should not have changed since the expected value " +
"did not match, hence exchanged should be false"
);
assertEquals(newValue,
valueUpdater.get(this),
"The value of the privateVolatile should still be 7");
}
@Test
@Tag("PASSING")
@Order(2)
public void compareAndSetUsingAtomicReferenceFieldUpdater() {
final AtomicReferenceFieldUpdater<TestKataCompareAndSet, Integer> valueUpdater =
AtomicReferenceFieldUpdater.newUpdater(TestKataCompareAndSet.class,
Integer.class,
"privateVolatile");
boolean exchanged = valueUpdater.compareAndSet(this, currentValue, newValue);
assertTrue(exchanged,
"The value should have been changed to 7, " +
"hence exchanged should be true"
);
assertEquals(newValue,
valueUpdater.get(this),
"The value of the privateVolatile should now be 7");
exchanged = valueUpdater.compareAndSet(this, 2, 33);
assertFalse(exchanged,
"The value should not have changed since the expected value " +
"did not match, hence exchanged should be false"
);
assertEquals(newValue,
valueUpdater.get(this),
"The value of the privateVolatile should still be 7");
}
public static void main(String[] args) {
Person person = new Person("zhangsan", 11, 170);
person.setHobby(new Hobby("打球", "足球,篮球"));
AtomicIntegerFieldUpdater<Person> atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(Person.class, "age");
atomicIntegerFieldUpdater.addAndGet(person, 12);
AtomicLongFieldUpdater<Person> atomicLongFieldUpdater = AtomicLongFieldUpdater.newUpdater(Person.class, "height");
atomicLongFieldUpdater.addAndGet(person, 180);
AtomicReferenceFieldUpdater<Person, Hobby> atomicReferenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Person.class, Hobby.class, "hobby");
atomicReferenceFieldUpdater.getAndSet(person, new Hobby("打球", "排球,羽毛球"));
}
/**
* Basic tests of the API : Simple function calls to exercise all of the functions listed in the API
* specification for the AtomicReferenceFieldUpdater class.
*/
public void testAPI()
{
// =================================================================================
// Create instances of AtomicReferenceFieldUpdater to work with
for(int i = 0; i < updaters.length; i++)
{
updaters[i] = AtomicReferenceFieldUpdater.newUpdater(AtomicTestObject.class, String.class, "volatileString");
}
// =================================================================================
// Basic API tests
assertEquals("1 : get()", "the answer", getRandomUpdater().get(testObject1));
assertEquals("2 : get()", getRandomUpdater().get(testObject1), getRandomUpdater().get(testObject2));
assertEquals("3 : get()", getRandomUpdater().get(testObject1), getRandomUpdater().get(testObject1));
assertEquals("4 : get()", getRandomUpdater().get(testObject2), getRandomUpdater().get(testObject2));
assertEquals("5 : getAndSet()", "the answer", getRandomUpdater().getAndSet(testObject1, "the question"));
assertEquals("6 : get()", "the question", getRandomUpdater().get(testObject1));
assertEquals("7 : getAndSet()", "the question", getRandomUpdater().getAndSet(testObject1, "the answer"));
assertEquals("8 : compareAndSet()", true, getRandomUpdater().compareAndSet(testObject1, "the answer", "the question"));
assertEquals("9 : compareAndSet()", true, getRandomUpdater().compareAndSet(testObject2, "the answer", "the question"));
assertEquals("10: get()", getRandomUpdater().get(testObject1), getRandomUpdater().get(testObject2));
assertEquals("11: compareAndSet()", false, getRandomUpdater().compareAndSet(testObject1, "the answer", "the question"));
assertEquals("12: compareAndSet()", true, getRandomUpdater().compareAndSet(testObject1, "the question", "the answer"));
}
public void checkPrivateAccess() {
try {
AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
shouldThrow();
} catch (RuntimeException success) {
assertNotNull(success.getCause());
}
}
public void checkCompareAndSetProtectedSub() {
AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
this.protectedField = one;
assertTrue(a.compareAndSet(this, one, two));
assertTrue(a.compareAndSet(this, two, m4));
assertSame(m4, a.get(this));
assertFalse(a.compareAndSet(this, m5, seven));
assertFalse(seven == a.get(this));
assertTrue(a.compareAndSet(this, m4, seven));
assertSame(seven, a.get(this));
}
public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
obj.x = one;
AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
assertSame(one, a.get(obj));
assertTrue(a.compareAndSet(obj, one, two));
assertSame(two, a.get(obj));
}
public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
try {
AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
throw new AssertionError("should throw");
} catch (RuntimeException success) {
assertNotNull(success.getCause());
}
}
/** compare raw numbers for atomic ops using JDK vs unsafe wrapper classes */
public void SW_testCompareAtomicOps() {
final AtomicIntegerFieldUpdater<ConcurrentMapOpsTest> intJDKCounter =
AtomicIntegerFieldUpdater.newUpdater(ConcurrentMapOpsTest.class,
"intJDKCounter");
final AtomicLongFieldUpdater<ConcurrentMapOpsTest> longJDKCounter =
AtomicLongFieldUpdater.newUpdater(ConcurrentMapOpsTest.class,
"longJDKCounter");
final AtomicReferenceFieldUpdater<ConcurrentMapOpsTest, LongRef>
refJDKCounter = AtomicReferenceFieldUpdater.newUpdater(
ConcurrentMapOpsTest.class, LongRef.class, "refJDKCounter");
final AtomicIntegerFieldUpdater<ConcurrentMapOpsTest> intUnsafeCounter =
AtomicUpdaterFactory.newIntegerFieldUpdater(ConcurrentMapOpsTest.class,
"intUnsafeCounter");
final AtomicLongFieldUpdater<ConcurrentMapOpsTest> longUnsafeCounter =
AtomicUpdaterFactory.newLongFieldUpdater(ConcurrentMapOpsTest.class,
"longUnsafeCounter");
final AtomicReferenceFieldUpdater<ConcurrentMapOpsTest, LongRef>
refUnsafeCounter = AtomicUpdaterFactory.newReferenceFieldUpdater(
ConcurrentMapOpsTest.class, LongRef.class, "refUnsafeCounter");
// some warmups
runAtomicOps(1, 50000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
// timed runs with single threads to see the raw overheads with no
// concurrency (as we would expect in most usual cases)
runAtomicOps(1, 50000000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
// now with concurrency
runAtomicOps(5, 2000000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
}
/**
* Creates and returns an updater for objects with the given reference field.
*/
public static <T, V> AtomicReferenceFieldUpdater<T, V> newReferenceFieldUpdater(
Class<T> tclass, Class<V> vclass, String fieldName) {
if (UnsafeHolder.hasUnsafe()) {
return new UnsafeAtomicReferenceUpdater<T, V>(tclass, vclass, fieldName);
}
else {
return AtomicReferenceFieldUpdater.newUpdater(tclass, vclass, fieldName);
}
}
static private void testAtomicReferenceFieldUpdater() {
System.out.println("AtomicTest.testAtomicReferenceFieldUpdater:");
AtomicTest obj = new AtomicTest();
AtomicReferenceFieldUpdater<AtomicTest, Integer> updater = AtomicReferenceFieldUpdater.newUpdater(AtomicTest.class, Integer.class, "value");
System.out.println(updater.get(obj));
updater.set(obj, 5);
System.out.println(updater.get(obj));
updater.compareAndSet(obj, 4, -4);
System.out.println(updater.get(obj));
updater.compareAndSet(obj, 5, -5);
System.out.println(updater.get(obj));
}
/**
* Creates and returns an updater for objects with the given field.
*
* @param tClass the class of the objects holding the field.
* @param vClass the class of the field
* @param fieldName the name of the field to be updated.
*/
public static <U, W> AtomicReferenceFieldUpdater<U, W> newAtomicReferenceFieldUpdater(
Class<U> tClass, Class<W> vClass, String fieldName) {
try {
if (UnsafeUtil.hasUnsafe()) {
return new UnsafeAtomicReferenceFieldUpdater<>(UnsafeUtil.getUnsafeAccessor().getUnsafe(), tClass, fieldName);
} else {
return AtomicReferenceFieldUpdater.newUpdater(tClass, vClass, fieldName);
}
} catch (Throwable t) {
return AtomicReferenceFieldUpdater.newUpdater(tClass, vClass, fieldName);
}
}
/** compare raw numbers for atomic ops using JDK vs unsafe wrapper classes */
public void SW_testCompareAtomicOps() {
final AtomicIntegerFieldUpdater<ConcurrentMapOpsTest> intJDKCounter =
AtomicIntegerFieldUpdater.newUpdater(ConcurrentMapOpsTest.class,
"intJDKCounter");
final AtomicLongFieldUpdater<ConcurrentMapOpsTest> longJDKCounter =
AtomicLongFieldUpdater.newUpdater(ConcurrentMapOpsTest.class,
"longJDKCounter");
final AtomicReferenceFieldUpdater<ConcurrentMapOpsTest, LongRef>
refJDKCounter = AtomicReferenceFieldUpdater.newUpdater(
ConcurrentMapOpsTest.class, LongRef.class, "refJDKCounter");
final AtomicIntegerFieldUpdater<ConcurrentMapOpsTest> intUnsafeCounter =
AtomicUpdaterFactory.newIntegerFieldUpdater(ConcurrentMapOpsTest.class,
"intUnsafeCounter");
final AtomicLongFieldUpdater<ConcurrentMapOpsTest> longUnsafeCounter =
AtomicUpdaterFactory.newLongFieldUpdater(ConcurrentMapOpsTest.class,
"longUnsafeCounter");
final AtomicReferenceFieldUpdater<ConcurrentMapOpsTest, LongRef>
refUnsafeCounter = AtomicUpdaterFactory.newReferenceFieldUpdater(
ConcurrentMapOpsTest.class, LongRef.class, "refUnsafeCounter");
// some warmups
runAtomicOps(1, 50000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
// timed runs with single threads to see the raw overheads with no
// concurrency (as we would expect in most usual cases)
runAtomicOps(1, 50000000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
// now with concurrency
runAtomicOps(5, 2000000, intJDKCounter, longJDKCounter, refJDKCounter,
intUnsafeCounter, longUnsafeCounter, refUnsafeCounter);
}
static <T, V> AtomicReferenceFieldUpdater<T, V> newRefUpdater(Class<T> tclass, Class<V> vclass, String fieldName) {
if (AVAILABLE) {
return AtomicReferenceFieldUpdater.newUpdater(tclass, vclass, fieldName);
} else {
return null;
}
}
private static AtomicReferenceFieldUpdater<SessionImpl, Object> createTokenUpdater() {
return AtomicReferenceFieldUpdater.newUpdater(SessionImpl.class, Object.class, "evictionToken");
}
private static AtomicReferenceFieldUpdater<SessionImpl, Object> createTokenUpdater() {
return AtomicReferenceFieldUpdater.newUpdater(SessionImpl.class, Object.class, "evictionToken");
}
AtomicReferenceFieldUpdater<Atomic8Test,Integer> anIntegerFieldUpdater() {
return AtomicReferenceFieldUpdater.newUpdater
(Atomic8Test.class, Integer.class, "anIntegerField");
}
static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
return AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
}
AtomicReferenceFieldUpdater<Atomic8Test,Integer> anIntegerFieldUpdater() {
return AtomicReferenceFieldUpdater.newUpdater
(Atomic8Test.class, Integer.class, "anIntegerField");
}
static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
return AtomicReferenceFieldUpdater.newUpdater
(AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
}