Mari kita lihat sebahagian daripada kod sumber dahulu:
public class AtomicLong extends Number implements java.io.Serializable { private static final long serialVersionUID = 1927816293512124184L; //1.获取Unsafe类实例 private static final Unsafe unsafe = Unsafe.getUnsafe(); //2.存放value的偏移量 private static final long valueOffset; static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); //3.用于判断是否支持Long类型无锁CAS private static native boolean VMSupportsCS8(); static { try { //4.获取value在AtomicLong中的偏移量 valueOffset = unsafe.objectFieldOffset (AtomicLong.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } //5.实际变量值 private volatile long value; /** * Creates a new AtomicLong with the given initial value. * * @param initialValue the initial value */ public AtomicLong(long initialValue) { value = initialValue; } ············省略部分代码············· }
Dalam kod di atas, instance kelas Unsafe diperoleh melalui Unsafe.getUnsafe() di kod 1 (kerana kelas AtomicLong berada di bawah pakej rt.jar, kelas AtomicLong dimuatkan melalui pemuat kelas Bootstarp). Pada kod 5, nilai diisytiharkan sebagai jenis yang tidak menentu untuk memastikan keterlihatan memori. Dapatkan offset pembolehubah nilai dalam kelas AtomicLong melalui kod 2 dan 4.
Seterusnya, mari perkenalkan fungsi utama dalam AtomicLong:
Kod kenaikan dan pengurangan
//调用unsafe方法,设置value=value+1后,返回原始的值 public final long getAndIncrement() { return unsafe.getAndAddLong(this, valueOffset, 1L); } //调用unsafe方法,设置value=value-1后,返回原始的值 public final long getAndDecrement() { return unsafe.getAndAddLong(this, valueOffset, -1L); } //调用unsafe方法,设置value=value+1后,返回递增后的值 public final long incrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; } //调用unsafe方法,设置value=value-1后,返回递减后的值 public final long decrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L; }
Empat di atas Operasi dilaksanakan secara dalaman dengan memanggil kaedah GetAndAddLong Unsafe Fungsi ini ialah operasi atom Parameter pertama di sini adalah rujukan kepada contoh AtomicLong, parameter kedua ialah nilai offset bagi pembolehubah nilai dalam AtomicLong, dan parameter ketiga ialah. nilai mengimbangi pembolehubah nilai dalam AtomicLong Parameter pertama ialah nilai pembolehubah kedua yang akan ditetapkan.
Logik pelaksanaan kaedah getAndIncrement() dalam JDK7 ialah:
public final long getAndIncrement() { while(true) { long current = get(); long next = current + 1; if (compareAndSet(current, next)) return current; } }
Dalam kod di atas, setiap utas mula-mula mendapat nilai semasa pembolehubah (kerana nilai ialah pembolehubah yang tidak menentu , jadi Ini adalah nilai terbaharu yang diperoleh), kemudian naikkannya sebanyak 1 dalam memori kerja, dan kemudian gunakan CAS untuk mengubah suai nilai pembolehubah Jika tetapan gagal, gelung akan terus mencuba sehingga tetapan berjaya.
Logik dalam JDK8 ialah:
public final long getAndIncrement() { retrturn unsafe.getAndAddLong(this, valueOffset, 1L); }
Kod unsafe.getAndAddLong dalam JDK8 ialah:
public final long getAndAddLong(Object var1, long var2, long var4) { long var6; do { var6 = this.getLongVolatile(var1, var2); } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4)); return var6; }
Seperti yang anda boleh lihat, logik gelung dalam AtomicLong dalam JDK7 telah terbina dalam oleh kelas operasi atom Tidak Selamat dalam JDK8.
boolean compareAndSet(jangkaan lama, kemas kini lama)
public final boolean compareAndSet(long expect,long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); }
Fungsi memanggil kaedah unsafe.compareAndSwapLong secara dalaman. Jika nilai dalam pembolehubah atom adalah sama dengan jangkaan, kemas kini nilai menggunakan nilai kemas kini dan kembalikan benar, jika tidak kembalikan palsu.
Atas ialah kandungan terperinci Analisis kod sumber kelas operasi atom Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!