Heim  >  Artikel  >  Java  >  Detaillierte Einführung in die Codefreigabe, die vom Atomic-Paket in Java verwendet wird

Detaillierte Einführung in die Codefreigabe, die vom Atomic-Paket in Java verwendet wird

黄舟
黄舟Original
2017-03-23 10:58:091192Durchsuche

Einführung

Java stellt seit JDK1.5 das Paket java.util.concurrent.atomic bereit, um Programmierern die Durchführung sperrenfreier atomarer Operationen in einer Multithread-Umgebung zu erleichtern. Die unterste Schicht der atomaren -Variable verwendet die vom Prozessor bereitgestellten atomaren Anweisungen, aber unterschiedliche CPU--Architekturen können unterschiedliche atomare Anweisungen bereitstellen und möglicherweise auch eine Art interne Sperre erfordern, daher ist dies der Fall Die Methode kann nicht absolut garantieren, dass der Thread nicht blockiert wird.

Einführung in das Atomic-Paket

Das Atomic-Paket enthält 12 Klassen und vier Atomic-Update-Methoden, nämlich den Atomic-Update-Basistyp, das Atomic-Update-Array, die Atomic-Update-Referenz und das Atomic-Update-Feld. Die Klassen im Atomic-Paket sind grundsätzlich Wrapper-Klassen, die mit Unsafe implementiert werden.

Atomic Update Basic Type Class

wird verwendet, um Basistypen atomar zu aktualisieren. Das Atomic-Paket stellt die folgenden drei Klassen bereit:

  • AtomicBoolean: Atomic Update Boolescher Typ.

  • AtomicInteger: Atomare Update-Ganzzahl.

  • AtomicLong: Atomic-Update lang.

Die gängigen Methoden von AtomicInteger sind wie folgt:

  • int addAndGet(int delta): Kombiniere den Eingabewert atomar mit dem Wert im Instanz (Wert in AtomicInteger) wird hinzugefügt und das Ergebnis wird zurückgegeben

  • boolean CompareAndSet(int Expect, Int Update): Wenn der Eingabewert gleich dem erwarteten Wert ist, ist der Wert atomar auf den eingegebenen Wert gesetzt.

  • int getAndIncrement(): Addiere atomar 1 zum aktuellen Wert. Hinweis: Der hier zurückgegebene Wert ist der Wert vor dem Inkrement.

  • void lazySet(int newValue): Es wird schließlich auf newValue gesetzt. Nach der Verwendung von lazySet zum Festlegen des Werts können andere Threads möglicherweise in kurzer Zeit noch den alten Wert lesen der Zeit.

  • int getAndSet(int newValue): Setzt den Wert atomar auf newValue und gibt den alten Wert zurück.

AtomicInteger-Beispielcode lautet wie folgt:

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest {

	static AtomicInteger ai = new AtomicInteger(1);

	public static void main(String[] args) {
		System.out.println(ai.getAndIncrement());
		System.out.println(ai.get());
	}

}

Ausgabe

1
2

Dessert

Das Atomic-Paket bietet drei Atomare Aktualisierungen von Grundtypen, aber zu den Grundtypen von Java gehören char, float, double usw. Die Frage ist also: Wie kann man andere Grundtypen atomar aktualisieren? Die Klassen im Atomic-Paket werden grundsätzlich mit Unsafe implementiert. Schauen wir uns den Quellcode von Unsafe an und stellen fest, dass Unsafe nur drei CAS-Methoden bereitstellt: CompareAndSwapObject, CompareAndSwapInt und CompareAndSwapLong Konvertiert einen Booleschen Wert in eine Ganzzahl und führt dann mit CompareAndSwapInt CAS aus, sodass eine atomare Aktualisierung von Double auch mit einer ähnlichen Idee implementiert werden kann.

Atomic Update Array Class

Aktualisieren Sie ein Element im Array atomar. Das Atomic-Paket stellt die folgenden drei Klassen bereit:

  • AtomicIntegerArray: Elemente atomar aktualisieren in einem Integer-Array.

  • AtomicLongArray: Atomare Aktualisierung von Elementen in einem Long-Integer-Array.

  • AtomicReferenceArray: Atomare Aktualisierung von Elementen in einem Referenztyp-Array.

Die AtomicIntegerArray-Klasse bietet hauptsächlich eine atomare Möglichkeit, die Ganzzahl im Array zu aktualisieren. Ihre allgemeinen Methoden sind wie folgt:

  • int addAndGet(int i, int delta): Fügt den Eingabewert atomar zum Element am Index i im Array hinzu.

  • boolean CompareAndSet(int i, int Expect, Int Update): Wenn der aktuelle Wert gleich dem erwarteten Wert ist, setzen Sie das Element an der Array-Position i atomar auf den Aktualisierungswert.

Der Beispielcode lautet wie folgt:

public class AtomicIntegerArrayTest {

	static int[] value = new int[] { 1, 2 };

	static AtomicIntegerArray ai = new AtomicIntegerArray(value);

	public static void main(String[] args) {
		ai.getAndSet(0, 3);
		System.out.println(ai.get(0));
                System.out.println(value[0]);
	}

}

Ausgabe

3
1

AtomicIntegerArray-Klasse Es ist zu beachten, dass der Array-Wert übergeben wird über den -Konstruktor Übergeben Sie es, und dann erstellt AtomicIntegerArray eine Kopie des aktuellen Arrays. Wenn AtomicIntegerArray also die internen Array-Elemente ändert, hat dies keine Auswirkungen auf das eingehende Array.

Atomic Update Reference Type

Atomic Update des Basistyps AtomicInteger kann nur eine Variable aktualisieren. Wenn Sie mehrere Variablen atomar aktualisieren möchten, müssen Sie die von dieser atomaren Update-Referenz bereitgestellte Klasse verwenden Typ. Das Atomic-Paket stellt die folgenden drei Klassen bereit:

  • AtomicReference: Atomic-Update-Referenztyp.

  • AtomicReferenceFieldUpdater: Aktualisiert Felder in Referenztypen atomar.

  • AtomicMarkableReference: Atomare Aktualisierung eines Referenztyps mit einem Markierungsbit. Es ist möglich, ein boolesches Flagbit und einen Referenztyp atomar zu aktualisieren. Die Konstruktionsmethode ist AtomicMarkableReference(V initialRef, boolean initialMark)

Der Beispielcode für die Verwendung von AtomicReference lautet wie folgt:

public class AtomicReferenceTest {

	public static AtomicReference<user> atomicUserRef = new AtomicReference</user><user>();

	public static void main(String[] args) {
		User user = new User("conan", 15);
		atomicUserRef.set(user);
		User updateUser = new User("Shinichi", 17);
		atomicUserRef.compareAndSet(user, updateUser);
		System.out.println(atomicUserRef.get().getName());
		System.out.println(atomicUserRef.get().getOld());
	}

	static class User {
		private String name;
		private int old;

		public User(String name, int old) {
			this.name = name;
			this.old = old;
		}

		public String getName() {
			return name;
		}

		public int getOld() {
			return old;
		}
	}
}

Ausgabe

Shinichi
17

Atom-Update-Feldklasse

Wenn wir nur ein bestimmtes Feld in einer bestimmten Klasse benötigen, müssen wir die Atomic-Update-Feldklasse verwenden. Das Atomic-Paket stellt die folgenden drei Klassen bereit:

  • AtomicIntegerFieldUpdater: Updater zum atomaren Aktualisieren von Ganzzahlfeldern.

  • AtomicLongFieldUpdater: Updater für die atomare Aktualisierung langer Ganzzahlfelder.

  • AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更数据和数据的版本号,可以解决使用CAS进行原子更新时,可能出现的ABA问题。

原子更新字段类都是抽象类,每次使用都时候必须使用静态方法newUpdater创建一个更新器。原子更新类的字段的必须使用public Volatile修饰符。AtomicIntegerFieldUpdater的例子代码如下:

public class AtomicIntegerFieldUpdaterTest {

	private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater
			.newUpdater(User.class, "old");

	public static void main(String[] args) {
		User conan = new User("conan", 10);
		System.out.println(a.getAndIncrement(conan));
		System.out.println(a.get(conan));
	}

	public static class User {
		private String name;
		public volatile int old;

		public User(String name, int old) {
			this.name = name;
			this.old = old;
		}

		public String getName() {
			return name;
		}

		public int getOld() {
			return old;
		}
	}
}

输出

10
11

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Codefreigabe, die vom Atomic-Paket in Java verwendet wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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