因爲在多線程條件下,若是對共享變量修改容易形成數據不一致的狀況,因此對於共享變量須要保證線程安全有有以下幾種方式:html
lock
或者synchronized
進行同步共享變量該類爲後者,基於CAS方式修改具備原子性。java
int
類型表示:1表示true 0表示falseUnsafe.compareAndSwant
方法底層經過CAS原理(CPU中cmpxchg指令)對值進行變化Cloneable
接口,能被克隆Serializable
接口,支持序列化傳輸private static final long serialVersionUID = 4654671469794556979L; // setup to use Unsafe.compareAndSwapInt for updates //使用unsafe類進行cas private static final Unsafe unsafe = Unsafe.getUnsafe(); //獲取該值得偏移量(內存中的地址) private static final long valueOffset; /** * 內部使用int來作boolean的設置 * 默認爲0 */ private volatile int value;
serialVersionUID
:序列化IDunsafe
:該類是Atomic中核心類,用於執行低級別,對內存進行操做,內部都是native
方法valueOffset
:字段value的內存偏移地址value
:真實value,1表示true 0表示false,使用volatile
保證內存可見性static { try { //返回對象成員屬性在內存地址相對於此對象的內存地址的偏移量 valueOffset = unsafe.objectFieldOffset (AtomicBoolean.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } }
主要是經過unsafe方法獲取value值得內存偏移地址數組
獲取該boolean變量安全
/** * 返回當前值 */ public final boolean get() { return value != 0; }
比較前值後賦值,可能存在賦值失敗的狀況多線程
/* * 只有當期待的值爲expect的時候纔會更新相關值 * 1. 期待的值等於如今值,則成功賦值,返回true * 2. 期待的值不等於如今的值,則賦值失敗,則返回false */ 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); }
compareAndSwapInt
進行CAS賦值比較前值後進行賦值,用的相對較多this
public final boolean getAndSet(boolean newValue) { boolean prev; do { prev = get(); } while (!compareAndSet(prev, newValue)); return prev; }
compareAndSet
進行CAS賦值無條件設置值,用的相對較少線程
public final void set(boolean newValue) { value = newValue ? 1 : 0; }
也是賦值操做,該操做會讓Java插入StoreStore內存屏障,避免發生寫操做重排序code
public final void lazySet(boolean newValue) { int v = newValue ? 1 : 0; unsafe.putOrderedInt(this, valueOffset, v); }
boolean
類,是線程安全的