Heim Java javaLernprogramm Beispiel für die Implementierung einer sperrenfreien Programmierung von CAS-Anweisungen durch Java

Beispiel für die Implementierung einer sperrenfreien Programmierung von CAS-Anweisungen durch Java

Sep 15, 2017 am 11:07 AM
java 实例 编程

In diesem Artikel wird hauptsächlich das Implementierungsbeispiel für die sperrenfreie Programmierung von cas-Anweisungen in der Java-Sprache vorgestellt. Es hat einen gewissen Referenzwert und Freunde in Not können mehr darüber erfahren.

Das erste Mal, dass Sie mit relevanten Inhalten in Kontakt kommen, ist das Schlüsselwort volatile. Sie wissen, dass es die Sichtbarkeit von Variablen gewährleisten und zur Implementierung atomarer Lese- und Schreiboperationen verwendet werden kann. . . Es gibt jedoch nichts, was Volatile tun kann, um einige zusammengesetzte Operationen zu implementieren. . . Die typischsten Vertreter sind Inkrementierungs- und Dekrementierungsoperationen. . . .

Wir wissen, dass in einer gleichzeitigen Umgebung der einfachste Weg, Datenkonsistenz zu erreichen, darin besteht, zu sperren, um sicherzustellen, dass nur ein Thread gleichzeitig mit den Daten arbeiten kann. . . . Ein Zähler kann beispielsweise folgendermaßen implementiert werden:


public class Counter {
  private volatile int a = 0;
  public synchronized int incrAndGet(int number) {
    this.a += number;
    return a;
  } 
  public synchronized int get() {
    return a;
  }
}
Nach dem Login kopieren

Wir modifizieren alle Operationen mit dem synchronisierten Schlüsselwort, um einen synchronen Zugriff auf das Attribut a sicherzustellen. . . Dies kann zwar die Konsistenz von a in einer gleichzeitigen Umgebung gewährleisten, aber aufgrund der Verwendung von Sperren, Sperren-Overhead, Thread-Planung usw. ist die Skalierbarkeit des Programms begrenzt, sodass es viele sperrenfreie Implementierungen gibt. . . .

Tatsächlich verwenden diese sperrfreien Methoden alle einige CAS-Anweisungen (Vergleichen und Wechseln), die vom Prozessor bereitgestellt werden. Was genau macht dieses CAS? Sie können die folgende Methode verwenden, um zu erklären, was CAS tut . Die dargestellte Semantik:


public synchronized int compareAndSwap(int expect, int newValue) {
    int old = this.a;
    if (old == expect) {
      this.a = newValue;
    }
    return old;
  }
Nach dem Login kopieren

Nun, das Gebot für die CAS-Semantik sollte durch den Code sehr klar sein. Es scheint, dass die meisten Prozessoren jetzt atomare CAS-Befehle implementieren. .
Okay, dann werfen wir einen Blick darauf, wo CAS in Java verwendet wird. Schauen wir uns zunächst den Typ AtomicInteger an. Dies ist ein Typ, der von der Parallelitätsbibliothek bereitgestellt wird:


private volatile int value;
Nach dem Login kopieren

Dies ist ein intern definiertes Attribut, das zum Speichern von Werten verwendet wird. Da es vom flüchtigen Typ ist, kann es die Sichtbarkeit zwischen Threads und die Atomizität des Lesens und Schreibens sicherstellen. . .
Dann werfen wir einen Blick auf einige der am häufigsten verwendeten Methoden:


public final int addAndGet(int delta) {
  for (;;) {
    int current = get();
    int next = current + delta;
    if (compareAndSet(current, next))
      return next;
  }
}
Nach dem Login kopieren

Die Funktion dieser Methode besteht hier darin, Delta zum aktuellen Wert hinzuzufügen Sie können sehen, dass es in der gesamten Methode keine Sperre gibt. Dieser Code ist tatsächlich eine Methode zum Implementieren eines sperrenfreien Zählers in Java. Die Methode „compareAndSet“ ist wie folgt definiert:


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

Da die unsichere Methode aufgerufen wird, können Sie nichts dagegen tun. Tatsächlich sollten Sie erraten können, dass die JVM die CAS-Anweisung des Prozessors selbst aufruft, um atomare Operationen zu implementieren. . .

Grundsätzlich werden die wichtigen Methoden des Typs AtomicInteger sperrenfrei implementiert. . Daher kann die Verwendung dieses Typs in einer gleichzeitigen Umgebung eine bessere Leistung erzielen. . .
Das Obige wurde abgeschlossen, um einen sperrenfreien Zähler in Java zu implementieren. Schauen wir uns als nächstes an, wie man einen sperrenfreien Stapel implementiert und den Code direkt einfügt. Der Code wird aus „JAVA Concurrent Programming in Action“ nachgeahmt ":


package concurrenttest;
import java.util.concurrent.atomic.AtomicReference;
public class ConcurrentStack<e> {
  AtomicReference<node<e>> top = new AtomicReference<node<e>>();
  public void push(E item) {
    Node<e> newHead = new Node<e>(item);
    Node<e> oldHead;
    while (true) {
      oldHead = top.get();
      newHead.next = oldHead;
      if (top.compareAndSet(oldHead, newHead)) {
        return;
      }
    }
  }
  public E pop() {
    while (true) {
      Node<e> oldHead = top.get();
      if (oldHead == null) {
        return null;
      }
      Node<e> newHead = oldHead.next;
      if (top.compareAndSet(oldHead, newHead)) {
        return oldHead.item;
      }
    }
  }
  private static class Node<e> {
    public final E item;
    public Node<e> next;
     
    public Node(E item) {
      this.item = item;
    }
  }
}
Nach dem Login kopieren

Okay, der obige Code implementiert ganz einfach einen sperrenfreien Stapel. . . In einer gleichzeitigen Umgebung können sperrenfreie Datenstrukturen viel besser skaliert werden als Sperren. . .
Wenn wir über sperrenfreie Programmierung sprechen, müssen wir sperrenfreie Warteschlangen erwähnen. Tatsächlich wurde die Implementierung sperrenfreier Warteschlangen in der gleichzeitigen Bibliothek bereitgestellt: ConcurrentLinkedQueue.


public boolean offer(E e) {
  checkNotNull(e);
  final Node<e> newNode = new Node<e>(e);
  for (Node<e> t = tail, p = t;;) {
    Node<e> q = p.next;
    if (q == null) {
      // p is last node
      if (p.casNext(null, newNode)) {
        // Successful CAS is the linearization point
        // for e to become an element of this queue,
        // and for newNode to become "live".
        if (p != t) // hop two nodes at a time
          casTail(t, newNode); // Failure is OK.
        return true;
      }
      // Lost CAS race to another thread; re-read next
    }
    else if (p == q)
      // We have fallen off list. If tail is unchanged, it
      // will also be off-list, in which case we need to
      // jump to head, from which all live nodes are always
      // reachable. Else the new tail is a better bet.
      p = (t != (t = tail)) ? t : head;
    else
      // Check for tail updates after two hops.
      p = (p != t && t != (t = tail)) ? t : q;
  }
}
Nach dem Login kopieren

Diese Methode wird verwendet, um Elemente am Ende der Warteschlange hinzuzufügen. Hier können Sie sehen, dass es für den spezifischen sperrfreien Algorithmus keine Sperre gibt. Michael-Scott hat einen nicht blockierenden Linked-List-Algorithmus vorgeschlagen. . . Um zu sehen, wie es konkret funktioniert, können Sie eine ausführlichere Einführung unter „JAVA Concurrent Programming in Practice“ finden.

Darüber hinaus werden andere Methoden tatsächlich sperrenfrei implementiert.

Schließlich ist es in der tatsächlichen Programmierung besser, diese sperrenfreien Implementierungen in einer gleichzeitigen Umgebung zu verwenden, da sie schließlich eine bessere Skalierbarkeit aufweisen.

Zusammenfassung

Das obige ist der detaillierte Inhalt vonBeispiel für die Implementierung einer sperrenfreien Programmierung von CAS-Anweisungen durch Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Der Schlüssel zum Programmieren: Die Leistungsfähigkeit von Python für Anfänger freischalten Der Schlüssel zum Programmieren: Die Leistungsfähigkeit von Python für Anfänger freischalten Oct 11, 2024 pm 12:17 PM

Python ist aufgrund seiner einfachen Erlernbarkeit und leistungsstarken Funktionen eine ideale Einführungssprache in die Programmierung für Anfänger. Zu seinen Grundlagen gehören: Variablen: werden zum Speichern von Daten (Zahlen, Zeichenfolgen, Listen usw.) verwendet. Datentyp: Definiert den Datentyp in der Variablen (Ganzzahl, Gleitkomma usw.). Operatoren: werden für mathematische Operationen und Vergleiche verwendet. Kontrollfluss: Kontrollieren Sie den Fluss der Codeausführung (bedingte Anweisungen, Schleifen).

Problemlösung mit Python: Erschließen Sie leistungsstarke Lösungen als Programmieranfänger Problemlösung mit Python: Erschließen Sie leistungsstarke Lösungen als Programmieranfänger Oct 11, 2024 pm 08:58 PM

Python unterstützt Anfänger bei der Problemlösung. Seine benutzerfreundliche Syntax, umfangreiche Bibliothek und Funktionen wie Variablen, bedingte Anweisungen und Schleifen ermöglichen eine effiziente Codeentwicklung. Von der Datenverwaltung über die Steuerung des Programmablaufs bis hin zur Ausführung wiederkehrender Aufgaben bietet Python

C entmystifizieren: Ein klarer und einfacher Weg für neue Programmierer C entmystifizieren: Ein klarer und einfacher Weg für neue Programmierer Oct 11, 2024 pm 10:47 PM

C ist eine ideale Wahl für Anfänger, um die Systemprogrammierung zu erlernen. Es enthält die folgenden Komponenten: Header-Dateien, Funktionen und Hauptfunktionen. Ein einfaches C-Programm, das „HelloWorld“ drucken kann, benötigt eine Header-Datei mit der Standard-Eingabe-/Ausgabe-Funktionsdeklaration und verwendet zum Drucken die printf-Funktion in der Hauptfunktion. C-Programme können mit dem GCC-Compiler kompiliert und ausgeführt werden. Nachdem Sie die Grundlagen beherrschen, können Sie mit Themen wie Datentypen, Funktionen, Arrays und Dateihandhabung fortfahren, um ein kompetenter C-Programmierer zu werden.

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Java leicht gemacht: Ein Leitfaden für Anfänger zur Programmierleistung Java leicht gemacht: Ein Leitfaden für Anfänger zur Programmierleistung Oct 11, 2024 pm 06:30 PM

Java leicht gemacht: Ein Leitfaden für Anfänger zur leistungsstarken Programmierung Java ist eine leistungsstarke Programmiersprache, die in allen Bereichen von mobilen Anwendungen bis hin zu Systemen auf Unternehmensebene verwendet wird. Für Anfänger ist die Syntax von Java einfach und leicht zu verstehen, was es zu einer idealen Wahl zum Erlernen des Programmierens macht. Grundlegende Syntax Java verwendet ein klassenbasiertes objektorientiertes Programmierparadigma. Klassen sind Vorlagen, die zusammengehörige Daten und Verhaltensweisen organisieren. Hier ist ein einfaches Java-Klassenbeispiel: publicclassPerson{privateStringname;privateintage;

Entfesseln Sie Ihren inneren Programmierer: C für absolute Anfänger Entfesseln Sie Ihren inneren Programmierer: C für absolute Anfänger Oct 11, 2024 pm 03:50 PM

C ist eine ideale Sprache für Anfänger zum Erlernen des Programmierens. Zu seinen Vorteilen gehören Effizienz, Vielseitigkeit und Portabilität. Das Erlernen der C-Sprache erfordert: Installieren eines C-Compilers (z. B. MinGW oder Cygwin) Verstehen von Variablen, Datentypen, bedingten Anweisungen und Schleifenanweisungen Schreiben des ersten Programms, das die Hauptfunktion und die printf()-Funktion enthält Üben durch praktische Fälle (z. B. Berechnen von Durchschnittswerten) C-Sprachkenntnisse

See all articles