// Use null as initial value to create new AtomicReference。 AtomicReference()
// Use given initialValue to create new AtomicReference。 AtomicReference(V initialValue)
// If current value == expected, then atomically update the value booleancompareAndSet(V expect, V update) // Get current value V get() // Atomically get the new value and return old value V getAndSet(V newValue) // Set the new value voidlazySet(V newValue) // Set the new value voidset(V newValue) // Atomically sets the value to newValue if the current value == expectedValue booleanweakCompareAndSet(V expect, V update)
Source code analyisi of AtomicReference
The source code of AtomicReference.java in JDK11.0.5 is as follows:
/** * Creates a new AtomicReference with the given initial value. * * @param initialValue the initial value */ publicAtomicReference(V initialValue){ value = initialValue; }
/** * Creates a new AtomicReference with null initial value. */ publicAtomicReference(){ }
/** * Returns the current value, * with memory effects as specified by {@link VarHandle#getVolatile}. * * @return the current value */ publicfinal V get(){ return value; }
/** * Sets the value to {@code newValue}, * with memory effects as specified by {@link VarHandle#setVolatile}. * * @param newValue the new value */ publicfinalvoidset(V newValue){ value = newValue; }
/** * Sets the value to {@code newValue}, * with memory effects as specified by {@link VarHandle#setRelease}. * * @param newValue the new value * @since 1.6 */ publicfinalvoidlazySet(V newValue){ VALUE.setRelease(this, newValue); }
/** * Atomically sets the value to {@code newValue} * if the current value {@code == expectedValue}, * with memory effects as specified by {@link VarHandle#compareAndSet}. * * @param expectedValue the expected value * @param newValue the new value * @return {@code true} if successful. False return indicates that * the actual value was not equal to the expected value. */ publicfinalbooleancompareAndSet(V expectedValue, V newValue){ return VALUE.compareAndSet(this, expectedValue, newValue); }
/** * Possibly atomically sets the value to {@code newValue} * if the current value {@code == expectedValue}, * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}. * * @deprecated This method has plain memory effects but the method * name implies volatile memory effects (see methods such as * {@link #compareAndExchange} and {@link #compareAndSet}). To avoid * confusion over plain or volatile memory effects it is recommended that * the method {@link #weakCompareAndSetPlain} be used instead. * * @param expectedValue the expected value * @param newValue the new value * @return {@code true} if successful * @see #weakCompareAndSetPlain */ @Deprecated(since="9") publicfinalbooleanweakCompareAndSet(V expectedValue, V newValue){ return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue); }
// other methods }
AtomicReference implements atomic operations through volatile and VarHandler.
value is volatile type. This ensures that when a thread modifies the value of a value, the value seen by other threads is the latest value, that is, the modified volatile value.
Set the value via VarHandler. This ensures that when a thread pool sets a value through a function (such as the compareAndSet function), its operation is atomic, that is, the thread will not be interrupted while operating on the value.
publicclassAtomicReferenceDemo{ publicstaticvoidmain(String[] args){ Person p1 = new Person(101); Person p2 = new Person(102);
// Create atomicReference, initialize as p1 AtomicReference ar = new AtomicReference(p1); // if ar's value is p1, then set it as p2 ar.compareAndSet(p1, p2);
When creating a new AtomicReference object ar, initialize it to p1.
Next, set it through the CAS function. If the value of ar is p1, then set it to p2.
Finally, get the object of ar and print the result. The result of p3.equals(p1) is false, because Person does not override the equals() method, but uses the equals() method inherited from Object.java. equals() in Object.java is actually called == To compare two objects, that is, whether the addresses of the two objects are equal.