Heim > Artikel > Backend-Entwicklung > Ausführliche Erläuterung der Verwendung von synchronisiert zum Implementieren eines Sperrcodes
In diesem Artikel wird erläutert, wie Sie einen Sperrcode mit Synchronisierung implementieren. Im Folgenden finden Sie einen praktischen Fall, auf den sich Freunde beziehen können.
Methode 1:
public synchronized void a(){ //TODO }
Methode 2:
public void b(){ synchronized(this){ //TODO } }
Von hier In beiden Fällen wird die Sperre zwischen {} hinzugefügt. Schauen wir uns an, wie die Sperre ausgeführt wird:
public void c() { lock.lock(); try { // TODO } finally { lock.unlock(); } }
Auf diese Weise wird die Sperre zwischen lock() hinzugefügt. und unlock(). Wenn Sie also eine Sperrfunktion implementieren möchten, müssen Sie darüber nachdenken, wie Sie diese beiden Methoden, die Methoden lock() und unlock(), implementieren. Definieren Sie zunächst ein FrameworkWie unten gezeigt:
public void lock(){ } public void unlock(){ }
Dann möchten Sie synchronisiert verwenden, um diese beiden Methoden zu implementieren.
Jetzt habe ich tatsächlich eine etwas klarere Vorstellung, aber ich weiß immer noch nicht, wie ich diese beiden Methoden ausfüllen soll. Ich werde die Eigenschaften von Lock später analysieren und mir diesen Code ansehen:
public void c() { lock.lock(); //When current thread get the lock, other thread has to wait try { //current thread get in the lock, other thread can not get in // TODO } finally { lock.unlock(); //current thread release the lock } }
Ich habe gerade einen kleinen Kommentar zu diesem Code hinzugefügt und nichts anderes getan. Hilft es, diesen Code zu verstehen? Häufiges Wort? Sollten wir beim Ausfüllen der Methoden lock() und unlock() auf das Schlüsselwort currentthread achten, um die Lösung zu finden? Die Antwort ist ja.
Analysieren Sie als Nächstes, wie der Thread bei Verwendung der Synchronisierung warten kann. Verwenden Sie die Methode wait(). Wie wecke ich den Thread auf? Verwenden Sie die notify()-Methode. Verwenden Sie dann die Methode wait() in der Methode lock() und die Methode notify() in der Methode unlock(). Es gibt also eine Bedingung, wenn wir wait() und notify() verwenden. Überlegen Sie, was wir als Bedingung verwenden sollten.
Wir sollten als Beurteilungsbedingung verwenden, ob die Sperre belegt ist. Überlegen Sie, ob wir diese Bedingung bei der Verwendung von synchronisiert verwendet haben.
Lassen Sie uns analysieren, wann die Sperre aufgehoben werden soll und welche Bedingungen verwendet werden. Denken Sie darüber nach, ob Thread B die Sperre aufheben kann. Natürlich nicht. Wenn B freigelassen werden könnte, würde das gegen das Prinzip verstoßen. Es muss sein, dass die Sperre von Thread A nur von Thread A aufgehoben werden kann. Die Beurteilungsbedingung besteht also darin, zu beurteilen, ob der Thread, der die Sperre hält, der aktuelle Thread ist. Wenn ja, kann er natürlich nicht freigegeben werden.
Schauen wir uns nun den vollständigen Code an:
package test.lock; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; public class NaiveLock { private static final long NONE = -1; private long owner = NONE; private Boolean isLooked() { return owner != NONE; } public synchronized void lock() { long currentThreadId = Thread.currentThread().getId(); if (owner == currentThreadId) { throw new IllegalStateException("Lock has been acquired by current thread"); } while (this.isLooked()) { System.out.println(String.format("thread %s is waitting lock", currentThreadId)); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } owner = currentThreadId; System.out.println(String.format("Lock is acquired by thread %s", owner)); } public synchronized void unlock() { if (!this.isLooked() || owner != Thread.currentThread().getId()) { throw new IllegalStateException("Only Lock owner can unlock the lock"); } System.out.println(String.format("thread %s is unlocking", owner)); System.out.println(); owner = NONE; notify(); } public static void main(String[] args) { final NaiveLock lock = new NaiveLock(); ExecutorService executor = Executors.newFixedThreadPool(20, new ThreadFactory() { private ThreadGroup group = new ThreadGroup("test thread group"); { group.setDaemon(true); } @Override public Thread newThread(Runnable r) { return new Thread(group, r); } } ); for (int i = 0; i < 20; i++) { executor.submit(new Runnable() { @Override public void run() { lock.lock(); System.out.println(String.format("thread %s is running...", Thread.currentThread().getId())); try { Thread.sleep(new Random().nextint(1000)); } catch (InterruptedException e) { e.printStackTrace(); } lock.unlock(); } } ); } } }
Führen Sie ihn aus und sehen Sie sich das Ergebnis an:
Lock is acquired by thread 8 thread 8 is running... thread 27 is waitting lock thread 26 is waitting lock thread 25 is waitting lock thread 24 is waitting lock thread 23 is waitting lock thread 22 is waitting lock thread 21 is waitting lock thread 20 is waitting lock thread 19 is waitting lock thread 18 is waitting lock thread 17 is waitting lock thread 16 is waitting lock thread 15 is waitting lock thread 14 is waitting lock thread 13 is waitting lock thread 12 is waitting lock thread 11 is waitting lock thread 10 is waitting lock thread 9 is waitting lock thread 8 is unlocking Lock is acquired by thread 27 thread 27 is running... thread 27 is unlocking Lock is acquired by thread 26 thread 26 is running... thread 26 is unlocking Lock is acquired by thread 25 thread 25 is running... thread 25 is unlocking Lock is acquired by thread 24 thread 24 is running... thread 24 is unlocking Lock is acquired by thread 23 thread 23 is running... thread 23 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 22 is unlocking Lock is acquired by thread 21 thread 21 is running... thread 21 is unlocking Lock is acquired by thread 20 thread 20 is running... thread 20 is unlocking Lock is acquired by thread 19 thread 19 is running... thread 19 is unlocking Lock is acquired by thread 18 thread 18 is running... thread 18 is unlocking Lock is acquired by thread 17 thread 17 is running... thread 17 is unlocking Lock is acquired by thread 16 thread 16 is running... thread 16 is unlocking Lock is acquired by thread 15 thread 15 is running... thread 15 is unlocking Lock is acquired by thread 14 thread 14 is running... thread 14 is unlocking Lock is acquired by thread 13 thread 13 is running... thread 13 is unlocking Lock is acquired by thread 12 thread 12 is running... thread 12 is unlocking Lock is acquired by thread 11 thread 11 is running... thread 11 is unlocking Lock is acquired by thread 10 thread 10 is running... thread 10 is unlocking Lock is acquired by thread 9 thread 9 is running... thread 9 is unlocking
Wenn Sie die for-Schleife auf 30 Mal ändern, sehen Sie sich das Ergebnis noch einmal an:
Lock is acquired by thread 8 thread 8 is running... thread 27 is waitting lock thread 26 is waitting lock thread 25 is waitting lock thread 24 is waitting lock thread 23 is waitting lock thread 22 is waitting lock thread 21 is waitting lock thread 20 is waitting lock thread 19 is waitting lock thread 18 is waitting lock thread 17 is waitting lock thread 16 is waitting lock thread 15 is waitting lock thread 14 is waitting lock thread 13 is waitting lock thread 12 is waitting lock thread 11 is waitting lock thread 10 is waitting lock thread 9 is waitting lock thread 8 is unlocking Lock is acquired by thread 27 thread 27 is running... thread 8 is waitting lock thread 27 is unlocking Lock is acquired by thread 27 thread 27 is running... thread 26 is waitting lock thread 27 is unlocking Lock is acquired by thread 27 thread 27 is running... thread 25 is waitting lock thread 27 is unlocking Lock is acquired by thread 24 thread 24 is running... thread 27 is waitting lock thread 24 is unlocking Lock is acquired by thread 23 thread 23 is running... thread 24 is waitting lock thread 23 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 23 is waitting lock thread 22 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 21 is waitting lock thread 22 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 20 is waitting lock thread 22 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 19 is waitting lock thread 22 is unlocking Lock is acquired by thread 22 thread 22 is running... thread 18 is waitting lock thread 22 is unlocking Lock is acquired by thread 17 thread 17 is running... thread 17 is unlocking Lock is acquired by thread 16 thread 16 is running... thread 16 is unlocking Lock is acquired by thread 15 thread 15 is running... thread 15 is unlocking Lock is acquired by thread 14 thread 14 is running... thread 14 is unlocking Lock is acquired by thread 13 thread 13 is running... thread 13 is unlocking Lock is acquired by thread 12 thread 12 is running... thread 12 is unlocking Lock is acquired by thread 11 thread 11 is running... thread 11 is unlocking Lock is acquired by thread 10 thread 10 is running... thread 10 is unlocking Lock is acquired by thread 9 thread 9 is running... thread 9 is unlocking Lock is acquired by thread 8 thread 8 is running... thread 8 is unlocking Lock is acquired by thread 26 thread 26 is running... thread 26 is unlocking Lock is acquired by thread 25 thread 25 is running... thread 25 is unlocking Lock is acquired by thread 27 thread 27 is running... thread 27 is unlocking Lock is acquired by thread 24 thread 24 is running... thread 24 is unlocking Lock is acquired by thread 23 thread 23 is running... thread 23 is unlocking Lock is acquired by thread 21 thread 21 is running... thread 21 is unlocking Lock is acquired by thread 20 thread 20 is running... thread 20 is unlocking Lock is acquired by thread 19 thread 19 is running... thread 19 is unlocking Lock is acquired by thread 18 thread 18 is running... thread 18 is unlocking
Ich glaube, dass Sie die Methoden beherrschen, nachdem Sie diese Fälle gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!
Verwandte Lektüre:
Das einfachste String-Matching-Algorithmus-Tutorial in PHP
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Verwendung von synchronisiert zum Implementieren eines Sperrcodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!