Heim  >  Artikel  >  Java  >  Ausführliche Erläuterung des Synchronized-Schlüsselworts in der Java-Multithread-Programmierung

Ausführliche Erläuterung des Synchronized-Schlüsselworts in der Java-Multithread-Programmierung

高洛峰
高洛峰Original
2017-01-05 14:43:381476Durchsuche

In diesem Artikel werden einige Wissenspunkte zum synchronisierten Schlüsselwort im JAVA-Multithreading als Objektsperre vorgestellt.

Bei der sogenannten Objektsperre handelt es sich um eine synchronisierte Sperre eines Objekts. Informationen zu Objektsperren finden Sie in diesem Artikel

1. Analyse

synchronisiert kann Instanzmethoden wie folgt ändern:

public class MyObject {
  synchronized public void methodA() {
    //do something....
  }

Hier sperrt das synchronisierte Schlüsselwort das aktuelle Objekt. Aus diesem Grund spricht man auch von einer Objektsperre.

Warum ist das aktuelle Objekt gesperrt? Da methodA() eine Instanzmethode ist, müssen Sie methodA() in der Form object.method() (obj.methodA()) aufrufen, wenn Sie methodA() ausführen möchten. obj ist ein Objekt der MyObject-Klasse. Synchronisierte Sperren das Objekt obj.

Der obige Code kann auch so geschrieben werden:

public class MyObject {
 
  public void methodA() {
    synchronized(this){
      //do something....
    }
  }

Das Merkmal ist: Wenn mehrere synchronisierte Instanzmethoden in der MyObject-Klasse definiert sind, wenn mehrere Threads dasselbe Objekt besitzen In der MyObject-Klasse können diese Methoden nur synchron ausgeführt werden. Das heißt, nach der Ausführung einer synchronisierten modifizierten Methode kann eine andere synchronisierte modifizierte Methode ausgeführt werden.

lautet wie folgt:

In der MyObject-Klasse gibt es zwei synchronisierte modifizierte Methoden.
public class MyObject {
 
  synchronized public void methodA() {
    //do something....
  }
 
  synchronized public void methodB() {
    //do some other thing
  }
}

Thread A führt MethodeA() aus
public class ThreadA extends Thread {
 
  private MyObject object;
//省略构造方法
  @Override
  public void run() {
    super.run();
    object.methodA();
  }
}

Thread B Führen Sie methodB() aus
public class ThreadB extends Thread {
 
  private MyObject object;
//省略构造方法
  @Override
  public void run() {
    super.run();
    object.methodB();
  }
}

Da Thread A und Thread B dasselbe MyObject-Klassenobjekt enthalten, müssen die beiden Threads zwar unterschiedliche Methoden aufrufen, aber es Beispielsweise muss Thread B warten, bis Thread A die Ausführung der Methode MethodeA() abgeschlossen hat, bevor er die Methode MethodeB() ausführen kann.
public class Run {
  public static void main(String[] args) {
    MyObject object = new MyObject();
 
    //线程A与线程B 持有的是同一个对象:object
    ThreadA a = new ThreadA(object);
    ThreadB b = new ThreadB(object);
    a.start();
    b.start();
  }
}

3. Fazit

Wie aus dem Obigen ersichtlich ist, umfasst der Umfang der in diesem Artikel beschriebenen synchronisierten Sperre das gesamte Objekt. Wenn in einer Klasse mehrere synchronisierte modifizierte Synchronisationsmethoden vorhanden sind und mehrere Threads dasselbe Objekt der Klasse (dasselbe Objekt der Klasse) enthalten, wird auch die Ausführung jeder Methode synchronisiert, obwohl sie unterschiedliche Methoden aufrufen.

Wenn zwischen den synchronisierten Methoden keine gemeinsam genutzten Variablen vorhanden sind oder keine Verbindung zwischen den Methoden besteht, diese aber nur synchron ausgeführt werden können, wirkt sich dies auf die Effizienz aus.

4. Anwendung – Synchronisiert verwenden, um das Lesen schmutziger Daten aufgrund von Dateninkonsistenzen zu vermeiden

Das folgende Beispiel:

methodA() ist für die Änderung des Benutzernamens und Passworts verantwortlich. In Wirklichkeit entspricht ein Benutzername einem Passwort.
public class MyObject {
 
  private String userName = "b";
  private String passWord = "bb";
   
  synchronized public void methodA(String userName, String passWord) {
    this.userName = userName;
    try{
      Thread.sleep(5000);
    }catch(InterruptedException e){
       
    }
    this.passWord = passWord;
  }
 
  synchronized public void methodB() {
    System.out.println("userName" + userName + ": " + "passWord" + passWord);
  }
}

methodB() ist für das Lesen des Benutzernamens und Passworts verantwortlich.

Wenn MethodeB() nicht durch Synchronized geändert wird, ruft Thread A MethodeA() auf und führt sie bis Zeile 7 aus, ändert den Benutzernamen und gibt die CPU aus irgendeinem Grund auf (z. B. Schlafen in Zeile 9).

Wenn Thread B zu diesem Zeitpunkt methodB() ausführt, ist der gelesene Benutzername der von Thread A geänderte Benutzername („a“), das Passwort ist jedoch das ursprüngliche Passwort („bb“). Weil Thread A in den Ruhezustand ging und keine Zeit hatte, das Passwort zu ändern.

Wenn Methode B () jedoch mit „synchronisiert“ geändert wird, kann Thread B nur warten, bis Thread A die Ausführung abgeschlossen hat (dh den Benutzernamen und das Kennwort geändert hat), bevor Methode B ausgeführt wird, um den Benutzernamen zu lesen und Passwort. Daher werden Dirty-Read-Probleme aufgrund von Dateninkonsistenzen vermieden.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für alle beim Erlernen der Java-Programmierung hilfreich sein wird.

Ausführlichere Erläuterungen zum Synchronized-Schlüsselwort in der Java-Multithread-Programmierung und verwandte Artikel finden Sie auf der chinesischen PHP-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