Heim Java javaLernprogramm So verwenden Sie die Methoden wait() und notify() in Java, um Instanzen gemeinsam genutzter Ressourcen zu betreiben

So verwenden Sie die Methoden wait() und notify() in Java, um Instanzen gemeinsam genutzter Ressourcen zu betreiben

Oct 11, 2017 am 09:52 AM
java notify wait

In diesem Artikel wird hauptsächlich detailliert beschrieben, wie Java die Methode wait() notify() zum Betreiben gemeinsamer Ressourcen verwendet. Interessierte Freunde können sich auf

Gemeinsame Java-Ressourcen beziehen >

1) Die Methoden wait(), notify() und notifyAll() sind lokale Methoden und letzte Methoden und können nicht überschrieben werden.

 2) Das Aufrufen der wait()-Methode eines Objekts kann den aktuellen Thread blockieren, und der aktuelle Thread muss den Monitor (d. h. die Sperre oder den Monitor) dieses Objekts besitzen

 3) Aufruf Die notify()-Methode eines Objekts kann einen Thread aufwecken, der auf den Monitor dieses Objekts wartet. Wenn mehrere Threads auf den Monitor dieses Objekts warten, kann nur einer der Threads aufgeweckt werden 🎜> 4) Rufen Sie die notifyAll()-Methode auf, um alle Threads aufzuwecken, die auf die Überwachung dieses Objekts warten.

In Java gibt es keine Methoden, die PV-Operationen ähneln, den gegenseitigen Ausschluss verarbeiten usw. Die Prozesssynchronisation von JAVA wird durch synchronisiert () erreicht. Es ist zu beachten, dass die synchronisierte () -Methode von Java dem sich gegenseitig ausschließenden Speicherblock im Betriebssystemkonzept ähnelt Ein Thread erwirbt die Speichersperre, andere Threads können nicht auf den Speicher zugreifen, wodurch einfache Synchronisations- und gegenseitige Ausschlussoperationen in Java realisiert werden. Wenn Sie dieses Prinzip verstehen, können Sie den Unterschied zwischen „synced(this)“ und „synchized(static XXX)“ für eine Speichersperre für einen Speicherblock verstehen. Das Schlüsselwort „this“ stellt ein Objekt der Klasse dar, also ist seine Speichersperre für das gleiche Objekt Sich gegenseitig ausschließende Operation, und statische Mitglieder sind exklusiv für die Klasse, und ihr Speicherplatz wird von allen Mitgliedern der Klasse gemeinsam genutzt. Dies führt dazu, dass synchronisiert() die statischen Mitglieder sperrt, was dem Sperren der Klasse entspricht , zwischen allen Mitgliedern der Klasse, um den gegenseitigen Ausschluss zu implementieren, kann nur ein Thread gleichzeitig auf Instanzen dieser Klasse zugreifen. Wenn Sie sich zwischen Threads gegenseitig aufwecken müssen, müssen Sie die Methoden wait() und nofity() der Object-Klasse verwenden.

Nachdem Sie so viel gesprochen haben, verstehen Sie es möglicherweise nicht. Lassen Sie uns das Problem anhand eines Beispiels veranschaulichen. Verwenden Sie Multithreading, um kontinuierliche 1,2,1,2,1,2,1,2 zu erreichen. 1,2 Ausgang.


Test:

package com.study.thread;
/**
 * 多线程
 * @ClassName: PrintFile 
 * @date 2017年10月10日 下午4:05:04
 */
public class PrintFile implements Runnable{
  //当前线程id
  private int id ;
  //共享资源
  public byte[] res ;
  
  //如果类里写了有参构造器,而任然想保留无参数构造方法,则必须显式的写出该方法。
  public PrintFile() {
    super();
//    System.out.println("我是构造器"); 
  }

  public PrintFile(int id, byte[] res) {
    //构造器中使用super()/this(),必须放在第一行。
    this(); 
    this.id = id;
    this.res = res;
  }

  //静态计数器
  public static int count = 5;
  
  @Override
  public void run() {
    synchronized (res) {
      while(count-->=0){
        try {
          res.notify();//唤醒其他线程中的某一个(唤醒等待res的其他线程,当前线程执行完后要释放锁)
          System.out.println("当前线程id值:"+id);
          
          res.wait();//当前线程阻塞,等待被唤醒
          System.out.println("现在执行的线程是"+Thread.currentThread().getName()+",--wait()后的代码继续执行:"+id);
          
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      return; 
    }
  }
}
Nach dem Login kopieren


Ergebnis:

package com.study.thread;

public class PrintFileTest {
 public static void main(String[] args) {
  byte[] res = new byte[]{0,1,2};//共享资源
  PrintFile p1 = new PrintFile(1, res);
  PrintFile p2 = new PrintFile(2, res);
  
  Thread t1 = new Thread(p1, "a");
  Thread t2 = new Thread(p2, "b");
    
  t1.start();
  t2.start();
 }
}
Nach dem Login kopieren
Aktueller Thread-ID-Wert :1

Aktueller Thread-ID-Wert: 2

Der aktuell ausgeführte Thread ist a, der Code nach --wait() wird weiterhin ausgeführt: 1

Aktueller Thread-ID-Wert: 1
Der aktuell ausgeführte Thread ist b, der Code nach --wait() wird weiterhin ausgeführt: 2
Aktueller Thread-ID-Wert: 2
Der aktuell ausgeführte Thread ist a, der Code nach --wait() wird weiterhin ausgeführt: 1
aktueller Thread-ID-Wert: 1
Der aktuell ausgeführte Thread ist b, --wait() Der Code nach --wait() wird weiterhin ausgeführt: 2
Aktueller Thread-ID-Wert: 2
Der Thread Derzeit wird ein,--wait() ausgeführt. Der folgende Code wird weiterhin ausgeführt: 1

Im Folgenden wird erklärt, warum ein solches Ergebnis auftritt:

Zuerst werden die Threads 1 und 2 gestartet Angenommen, Thread 1 führt zuerst die Ausführungsmethode aus, um Ressourcen abzurufen (tatsächlich ist dies ungewiss), erhält die Sperre von Objekt a und tritt in die while-Schleife ein (wird zur Steuerung mehrerer Ausgaberunden verwendet):

1 Zu diesem Zeitpunkt ruft das Objekt seine Weckmethode notify() auf, was bedeutet, dass dieser Synchronisationsblock ausgeführt wird. Nach Abschluss gibt es die Sperre frei und übergibt sie an den Thread, der auf Ressource a wartet

2. Ausgabe 1;

3. Das Objekt führt die Wartemethode aus, was bedeutet, dass es von diesem Moment an der Thread der Objektsperre (hier Thread Nr. 1) ist, der die CPU-Steuerung freigibt. hebt die Sperre auf und der Thread wechselt in den blockierten Zustand. Der nachfolgende Code wird vorübergehend nicht ausgeführt, sodass 1 keine Auswirkung hat.

Irgendwann zuvor wurde Thread 2 ausgeführt Die Ausführungsmethode konnte jedoch nicht weiter ausgeführt werden, da sie die Sperre von Objekt a nicht erhalten hat. Nach drei Schritten wurde jedoch die Aktivierung von a durchgeführt. ) bedeutet auf die gleiche Weise, dass nach der Ausführung des Synchronisationsblocks die Sperre an den Thread übergeben wird, der auf eine Ressource wartet

5 6. Das Ausführen der Wartemethode von a bedeutet, dass der Thread, der ab diesem Zeitpunkt die Objektsperre besitzt (hier Thread Nr. 2), die CPU-Steuerung freigibt, die Sperre aufhebt und der Thread in den Blockierungszustand wechselt nicht vorübergehend ausgeführt werden, da der Synchronisierungsblock noch nicht ausgeführt wurde. Die 4-stufige Aktivierungsmethode von Thread Nr. 2 funktioniert zu diesem Zeitpunkt nicht. 1 führt Schritt 3 aus und stellt fest, dass die Objektsperre nicht verwendet wird, und führt daher weiterhin Schritt 3 aus. Im Code nach der Wartemethode lautet die Ausgabe: ------Thread 1 erhält die Sperre und der Code danach wait() läuft weiter: 1;

8 Zu diesem Zeitpunkt erfüllt die while-Schleife die Bedingungen und wird weiterhin ausgeführt. Führen Sie daher die Weckmethode von Thread Nr. 1 erneut aus es wird die Sperre aufheben, nachdem der Synchronisationsblock ausgeführt wurde;

10. Führen Sie die Wartemethode aus und geben Sie die Ressourcensperre auf >

11. Zu diesem Zeitpunkt hat Thread 2 die Sperre erneut erhalten und führt den Code nach der Wartemethode weiter aus. Die Ausgabe lautet also: ------Thread 2 erhält die Sperre. Warten Sie, bis der Code nach () weiterläuft:

12 Führen Sie die While-Schleife weiter aus und geben Sie 2 aus Ich glaube, dass jeder die Verwendung dieser beiden Methoden bereits verstanden hat, aber es gibt immer noch ein Problem in diesem Programm. Wenn die While-Schleife die Bedingungen nicht erfüllt, werden definitiv noch Threads auf Ressourcen warten, also der Hauptthread wird niemals enden. Der Zweck dieses Programms besteht natürlich nur darin, die Verwendung dieser beiden Methoden zu demonstrieren.

Zusammenfassung:

Die Methode wait() und notify() müssen zusammen mit synchronisiert(resource) verwendet werden. Das heißt, warten und benachrichtigen, um den Thread zu bearbeiten, der die Ressourcensperre erhalten hat. Aus syntaktischer Sicht müssen sich Obj.wait() und Obj.notify innerhalb des synchronisierten (Obj){...}-Anweisungsblocks befinden. Funktionell gesehen gibt der wait()-Thread nach dem Erwerb der Objektsperre aktiv die CPU-Steuerung und die Objektsperre frei und schläft gleichzeitig. Bis ein anderer Thread notify() des Objekts aufruft, um den Thread aufzuwecken, kann er weiterhin die Objektsperre erwerben und die Ausführung fortsetzen. Die entsprechende notify() ist die Freigabeoperation der Objektsperre. [Daher können wir feststellen, dass sowohl die Warte- als auch die Notify-Methode die Sperre des Objekts aufheben können, aber Wait gibt auch die CPU-Steuerung frei, d CPU-Steuerung sofort, aber die Sperre wird automatisch aufgehoben, nachdem die Ausführung des entsprechenden Anweisungsblocks „synchonized(){}“ endet. 】Nach dem Aufheben der Sperre wählt die JVM einen Thread unter den Threads aus, die auf Ressourcen warten, erteilt ihm die Objektsperre, weckt den Thread auf und setzt die Ausführung fort. Dies ermöglicht Synchronisations- und Weckvorgänge zwischen Threads. Sowohl Thread.sleep() als auch Object.wait() können den aktuellen Thread anhalten und die CPU-Steuerung freigeben. Der Hauptunterschied besteht darin, dass Object.wait() die Objektsperrsteuerung freigibt, während die CPU im Synchronisationsblock ist. Die Methode sleep() gibt die Sperre nicht frei, sondern nur die CPU-Steuerung.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie die Methoden wait() und notify() in Java, um Instanzen gemeinsam genutzter Ressourcen zu betreiben. 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ß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)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

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

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

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

Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Feb 07, 2025 pm 12:11 PM

Spring Boot vereinfacht die Schaffung robuster, skalierbarer und produktionsbereiteter Java-Anwendungen, wodurch die Java-Entwicklung revolutioniert wird. Der Ansatz "Übereinkommen über Konfiguration", der dem Feder -Ökosystem inhärent ist, minimiert das manuelle Setup, Allo

See all articles