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; } } }
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(); } }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: 1Aktueller 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:
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!