在Java的多線程開(kāi)發(fā)中需要做一些同步的操作。
在java concurrent庫(kù)中提供了一系列支持原子操作的類(lèi)钥星,在atomic包下。
這里分析其中的AtomicInteger源碼姆坚,來(lái)看看他是如何實(shí)現(xiàn)原子操作的笆搓。
AtomicInteger源碼比較簡(jiǎn)單,主要的操作是對(duì)一個(gè)int值進(jìn)行加減操作玄柏。
但是其中應(yīng)用到了一個(gè)神奇的類(lèi)Unsafe.java.
Unsafe.java提供了一些列的方法支持對(duì)JVM內(nèi)存的操作(當(dāng)然了他提供的功能遠(yuǎn)遠(yuǎn)不止操作內(nèi)存)襟衰。
你看的沒(méi)錯(cuò)是直接的操作內(nèi)存,這個(gè)對(duì)于習(xí)慣了寫(xiě)Java程序時(shí)由GC直接管理內(nèi)存的我這個(gè)小白來(lái)說(shuō)粪摘,簡(jiǎn)直是三觀盡毀瀑晒。
Unsafe.java竟然是反Java常規(guī)的,那么想要使用它也不是那么隨便的徘意。默認(rèn)Unsafe.java只信任JDK中的類(lèi)苔悦,所以在自定義的類(lèi)中不能直接實(shí)例化這個(gè)類(lèi),當(dāng)然你還是可以通過(guò)反射來(lái)獲取該對(duì)象椎咧。(額玖详,扯遠(yuǎn)了)
通過(guò)觀察代碼發(fā)現(xiàn)AtomicInteger的原子性就是通過(guò)Unsafe.java來(lái)實(shí)現(xiàn)的。主要代碼如下:
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private volatile int value; //注意value變量的volatile屬性
功能:
- 獲取Unsafe對(duì)象
- 通過(guò)反射獲取AtomicInteger類(lèi)中value在內(nèi)存中的位置邑退。
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
功能:
通過(guò)CAS算法竹宋,設(shè)置value的值。CAS算法就是先比較value的值和expect的值是否相同地技,如果相同就設(shè)置update蜈七。如果不相同則設(shè)置失敗。
這樣就保證了莫矗,對(duì)value的原子操作飒硅。