Heim > Java > javaLernprogramm > Analyse des Quellcodes der Java-Atomic-Operationsklasse

Analyse des Quellcodes der Java-Atomic-Operationsklasse

WBOY
Freigeben: 2023-04-21 11:31:07
nach vorne
1389 Leute haben es durchsucht

Werfen wir zunächst einen Blick auf einen Teil des Quellcodes:

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;
    }
    ············省略部分代码·············
}
Nach dem Login kopieren

Im obigen Code wird die Instanz der Unsafe-Klasse über Unsafe.getUnsafe() bei Code 1 abgerufen (da die AtomicLong-Klasse unter der rt. jar-Paket und die AtomicLong-Klasse wird übergeben und vom Bootstarp-Klassenlader geladen). Bei Code 5 wird der Wert als flüchtiger Typ deklariert, um die Sichtbarkeit des Speichers sicherzustellen. Ermitteln Sie den Offset der Wertvariablen in der AtomicLong-Klasse über die Codes 2 und 4.

Als nächstes stellen wir die Hauptfunktionen in AtomicLong vor:

  • Inkrement- und Dekrementierungscode

//调用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;
}
Nach dem Login kopieren

Die oben genannten vier Funktionen werden intern durch Aufrufen der getAndAddLong-Methode von Unsafe implementiert. Diese Funktion ist eine atomare Operation ein Verweis auf die AtomicLong-Instanz, der zweite Parameter ist der Offset-Wert der Wertvariablen in AtomicLong und der dritte Parameter ist der Wert der zweiten festzulegenden Variablen.

Die Implementierungslogik der getAndIncrement()-Methode in JDK7 lautet:

public final long getAndIncrement() {
    while(true) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}
Nach dem Login kopieren

Im obigen Code erhält jeder Thread zuerst den aktuellen Wert der Variablen (da der Wert eine flüchtige Variable ist, ist dies also der zuletzt erhaltene Wert). und dann im Arbeitsspeicher um 1 erhöhen und dann den Wert der Variablen mit CAS ändern. Wenn die Einstellung fehlschlägt, versucht die Schleife weiter, bis die Einstellung erfolgreich ist.

Die Logik in JDK8 lautet:

public final long getAndIncrement() {
        retrturn unsafe.getAndAddLong(this, valueOffset, 1L);
    }
Nach dem Login kopieren

Der Code von unsafe.getAndAddLong in JDK8 lautet:

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;
}
Nach dem Login kopieren

Es ist ersichtlich, dass die Schleifenlogik in AtomicLong in JDK7 durch die atomare Operationsklasse Unsafe in ersetzt wurde JDK8 Eingebaut. Die Funktion

  • Boolean CompareAndSet(long Expect, Long Update)

public final boolean compareAndSet(long expect,long update) 
{
    return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
Nach dem Login kopieren

ruft intern die Methode unsafe.compareAndSwapLong auf. Wenn der Wert in der atomaren Variablen dem erwarteten Wert entspricht, aktualisieren Sie den Wert mithilfe des Aktualisierungswerts und geben Sie „true“ zurück, andernfalls geben Sie „false“ zurück.

Das obige ist der detaillierte Inhalt vonAnalyse des Quellcodes der Java-Atomic-Operationsklasse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage