- Basic Classes:
- AtomicInteger
- AtomicLong
- AtomicBoolean
- Array type:
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
introduce
Since changes to shared variables can easily cause data inconsistencies under multithreaded conditions, there are several ways to ensure thread security for shared variables:
- Use lock or synchronized to synchronize shared variables
- Use CAS method to ensure that modified variables are atomic
This class is the latter and is atomistic based on CAS modification.
Implementation Principle
- Converts a true in boolean to an int type representation: 1 for true 0 for false
- Gets the memory address of the value when the class is initialized
- Calling the Unsafe.compareAndSwant method changes the value through CAS principles (the cmpxchg directive in the CPU)
Characteristic
- Thread Security Based on CAS
- Cloneable interface is implemented and can be cloned
- Serializable interface implemented to support serialization transfer
Source Parsing
Member variables
private static final long serialVersionUID = 4654671469794556979L; // setup to use Unsafe.compareAndSwapInt for updates //cas using unsafe class private static final Unsafe unsafe = Unsafe.getUnsafe(); //Get the value offset (address in memory) private static final long valueOffset; /** * Use int internally for boolean settings * Default 0 */ private volatile int value;
- serialVersionUID: Serialized ID
- unsafe: This class is the core class in Atomic and is used to perform low-level, memory manipulation, and internal native methods
- valueOffset: Memory offset address of field value
- Value: true value,1 true 0 false, volatile to ensure memory visibility
Class initialization process
static { try { //Returns the offset of the object member property from the memory address of this object valueOffset = unsafe.objectFieldOffset (AtomicBoolean.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } }
The main way to get a value-worth memory offset address is through the unsafe method
Member Method
get()
Get the boolean variable
/** * Return current value */ public final boolean get() { return value != 0; }
boolean compareAndSet(boolean expect, boolean update)
Comparing before and after assignments, assignment failures may occur
/* * Relevant values are updated only when the expected value is expect * 1. Expected value equal to present value, assign successfully, return true * 2. If the expected value is not equal to the present value, the assignment fails and false is returned */ public final boolean compareAndSet(boolean expect, boolean update) { int e = expect ? 1 : 0; int u = update ? 1 : 0; return unsafe.compareAndSwapInt(this, valueOffset, e, u); }
- Convert boolean to int type
- Call compareAndSwapInt for CAS assignment
- Returning true indicates success and false indicates failure
boolean getAndSet(boolean newValue)
Assigning values after comparing them uses relatively more
public final boolean getAndSet(boolean newValue) { boolean prev; do { prev = get(); } while (!compareAndSet(prev, newValue)); return prev; }
- Get the previous value first
- CAS assignment in call to loop compareAndSet
void set(boolean newValue)
Set values unconditionally, using relatively few
public final void set(boolean newValue) { value = newValue ? 1 : 0; }
void lazySet(boolean newValue)
It is also an assignment operation that causes Java to insert into the StoreStore memory barrier to avoid reordering write operations
public final void lazySet(boolean newValue) { int v = newValue ? 1 : 0; unsafe.putOrderedInt(this, valueOffset, v); }
summary
- This class is an atomic boolean class and is thread safe
- The core operations of this atomic class are based on the Unsafe class
- CAS generally produces ABA problems