Heim  >  Artikel  >  Java  >  So implementieren Sie die Thread-Synchronisierung in Java

So implementieren Sie die Thread-Synchronisierung in Java

王林
王林Original
2019-12-03 16:18:063336Durchsuche

So implementieren Sie die Thread-Synchronisierung in Java

Methode 1: Verwenden Sie das synchronisierte Schlüsselwort

Da jedes Objekt in Java über eine integrierte Sperre verfügt, wenn Sie dieses Schlüsselwort zum Ändern verwenden method schützt eine integrierte Sperre die gesamte Methode. Bevor Sie diese Methode aufrufen, müssen Sie die integrierte Sperre erhalten, andernfalls wird sie blockiert.

Hinweis: Das synchronisierte Schlüsselwort kann auch statische Methoden ändern. Wenn die statische Methode zu diesem Zeitpunkt aufgerufen wird, wird die gesamte Klasse gesperrt.

Hinweis: Die Synchronisierung ist ein Vorgang mit hohem Overhead, daher sollte der synchronisierte Inhalt minimiert werden. Normalerweise ist es nicht erforderlich, die gesamte Methode zu synchronisieren. Verwenden Sie einfach synchronisierte Codeblöcke, um den Schlüsselcode zu synchronisieren.

Das synchronisierte Schlüsselwort wird zum Schutz freigegebener Daten verwendet. Bitte achten Sie auf „gemeinsame Daten“. Sie müssen unterscheiden, welche Daten geteilte Daten sind >

Methode 2: Warten und benachrichtigen

wait(): Versetzt einen Thread in einen Wartezustand und gibt die Sperre des von ihm gehaltenen Objekts frei.

sleep(): Versetzt einen laufenden Thread in den Ruhezustand. Rufen Sie diese Methode auf, um InterruptedException abzufangen.

notify(): Beachten Sie, dass Sie beim Aufrufen dieser Methode einen Thread im Wartezustand nicht genau aktivieren können. Stattdessen bestimmt die JVM, welcher Thread aktiviert werden soll Nicht nach Priorität. Allnotity(): Weckt alle Threads im Wartezustand auf. Beachten Sie, dass Sie nicht allen geweckten Threads eine Objektsperre geben, sondern sie konkurrieren lassen.

Methode 3: Verwenden Sie spezielle Domänenvariablen volatile, um eine Thread-Synchronisierung zu erreichen

Das Schlüsselwort a.volatile bietet einen sperrfreien Mechanismus für den Zugriff auf Domänenvariablen

b. Die Verwendung von volatile zum Ändern eines Felds entspricht der Mitteilung an die virtuelle Maschine, dass das Feld möglicherweise von anderen Threads aktualisiert wird.

c Daher muss das Feld jedes Mal neu berechnet werden, anstatt den Wert zu verwenden im Register d.volatile stellt keine atomaren Operationen bereit und kann auch nicht zum Ändern endgültiger Typvariablen verwendet werden

Zum Beispiel:

Im obigen Beispiel nur Vor dem Konto hinzufügen Durch flüchtige Änderungen kann eine Thread-Synchronisierung erreicht werden.

package com.gcc.interview.synchro;
public class MybanRunnable implements Runnable{
	private Bank bank;
	public MybanRunnable(Bank bank) {
		this.bank = bank;
	}
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			bank.save1(100);
			System.out.println("账户余额是---"+bank.getAccount());
		}
	}
}

Hinweis: Das Nichtsynchronisationsproblem beim Multithreading tritt hauptsächlich beim Lesen und Schreiben von Feldern auf. Wenn das Feld selbst dieses Problem vermeidet, besteht keine Notwendigkeit, die Methode zur Feldbedienung zu ändern. Durch die Verwendung von endgültigen Feldern, sperrgeschützten Feldern und flüchtigen Feldern können Nichtsynchronisierungsprobleme vermieden werden.

Methode 4: Wiedereintrittssperren verwenden, um Thread-Synchronisierung zu erreichen

Ein neues java.util.concurrent-Paket wurde in JavaSE5.0 hinzugefügt, um die Synchronisierung zu unterstützen.

Die ReentrantLock-Klasse ist eine wiedereintrittsfähige, sich gegenseitig ausschließende Sperre, die die Lock-Schnittstelle implementiert. Sie weist das gleiche grundlegende Verhalten und die gleiche Semantik wie die Verwendung synchronisierter Methoden und Blöcke auf und erweitert ihre Fähigkeiten.

Gemeinsame Methoden der ReenreantLock-Klasse sind:

Hinweis: ReentrantLock() verfügt auch über eine Konstruktionsmethode, die eine faire Sperre erstellen kann, aber weil dies der Fall ist Die Effizienz der Programmausführung wird stark reduziert.

package com.gcc.interview.synchro;
class Bank{
	private int account = 100;
	
	public int getAccount() {
		return account;
	}
	//同步方法
	public synchronized void save(int money) {
		account+=money;
	}
	public void save1(int money) {
		//同步代码块
		synchronized(this) {
			account+=money;
		}
	}
	public void userThread() {
		Bank bank = new Bank();
		MybanRunnable my1 = new MybanRunnable(bank);
		System.out.println("线程1");
		Thread th1 = new Thread(my1);
		th1.start();
		System.out.println("线程2");
		Thread th2 = new Thread(my1);
		th2.start();
	}
}

Hinweis: Bezüglich der Auswahl des Sperrobjekts und des synchronisierten Schlüsselworts:

a Es ist am besten, beides nicht zu verwenden und ein java.util zu verwenden .concurrent-Paket Der bereitgestellte Mechanismus kann Benutzern helfen, mit allen sperrbezogenen Codes umzugehen.

So implementieren Sie die Thread-Synchronisierung in Javab. Wenn das synchronisierte Schlüsselwort die Anforderungen der Benutzer erfüllen kann, verwenden Sie synchronisiert, da es den Code vereinfachen kann.

c Wenn Sie erweiterte Funktionen benötigen, verwenden Sie die ReentrantLock-Klasse Achten Sie darauf, die Sperre rechtzeitig aufzuheben, da sonst ein Deadlock auftritt. Normalerweise wird die Sperre im endgültigen Code aufgehoben

Methode 5: Verwenden Sie lokale Variablen, um eine Thread-Synchronisation zu erreichen

Wenn Sie ThreadLocal zum Verwalten von Variablen verwenden, erhält jeder Thread, der die Variable verwendet, eine Kopie der Variablen, und die Kopien sind unabhängig voneinander, sodass jeder Thread seine eigene Kopie der Variablen nach Belieben ändern kann, ohne andere zu beeinflussen Threads.

Gemeinsame Methoden der ThreadLocal-Klasse

//只给出要修改的代码,其余代码与上同
        class Bank {
            //需要同步的变量加上volatile
            private volatile int account = 100;
            public int getAccount() {
                return account;
            }
            //这里不再需要synchronized 
            public void save(int money) {
                account += money;
            }
        }

Hinweis: ThreadLocal und der Synchronisationsmechanismus

a.ThreadLocal und der Synchronisationsmechanismus dienen beide zur Lösung mehrerer Probleme Probleme Zugriffskonfliktproblem derselben Variablen in Threads.

b. Ersteres übernimmt die Methode des „Austauschs von Raum gegen Zeit“, während letzteres die Methode des „Austauschs von Zeit gegen Raum“ übernimmt.

So implementieren Sie die Thread-Synchronisierung in JavaEmpfohlene verwandte Artikel und Tutorials:

Erste Schritte mit Java von Grund auf

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Thread-Synchronisierung in Java. 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