Als Tool zum gleichzeitigen Datenaustausch und zur Gewährleistung der Konsistenz verfügen Sperren über mehrere Implementierungen auf der JAVA-Plattform (z. B. synchronisiert und ReentrantLock usw.). Diese bereits geschriebenen Sperren erleichtern unsere Entwicklung, die spezifische Art und der Typ der Sperren werden jedoch selten erwähnt. In dieser Artikelserie werden gängige Sperrnamen und -merkmale unter JAVA analysiert, um Ihre Fragen zu beantworten.
4. Wiedereintrittssperre:
In diesem Artikel geht es um Wiedereintrittssperren im weitesten Sinne, nicht nur um ReentrantLock unter JAVA.
Wiedereintrittssperren, auch rekursive Sperren genannt, bedeuten, dass die innere rekursive Funktion nach dem Erlangen der Sperre durch die äußere Funktion desselben Threads immer noch über den Code zum Erlangen der Sperre verfügt, dieser jedoch nicht betroffen ist.
In der JAVA-Umgebung sind ReentrantLock und synchronisiert beide Wiedereintrittssperren.
Hier sind Anwendungsbeispiele:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse Test implementiert Runnable{
öffentliches synchronisiertes void get(){
System.out.println(Thread.currentThread().getId());
Satz();
}
öffentliches synchronisiertes void set(){
System.out.println(Thread.currentThread().getId());
}
@Override
public void run() {
erhalten();
}
public static void main(String[] args) {
Testen Sie ss=new Test();
neuer Thread(ss).start();
neuer Thread(ss).start();
neuer Thread(ss).start();
}
}
Die Endergebnisse beider Beispiele sind korrekt, das heißt, dieselbe Thread-ID wird zweimal hintereinander ausgegeben.
Das Ergebnis ist wie folgt:
Kopieren Sie den Codecode wie folgt:
Threadid: 8
Threadid: 8
Threadid: 10
Threadid: 10
Threadid: 9
Threadid: 9
Die wichtigste Aufgabe wiedereintrittsfähiger Sperren besteht darin, Deadlocks zu vermeiden.
Nehmen wir als Beispiel Spin Lock.
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse SpinLock {
private AtomicReference<Thread>owner =new AtomicReference<>();
public void lock(){
Thread current = Thread.currentThread();
while(!owner.compareAndSet(null, current)){
}
}
public void unlock (){
Thread current = Thread.currentThread();
owner.compareAndSet(current, null);
}
}
Für Spin-Locks:
1. Wenn derselbe Thread lock() zweimal aufruft, wird die Sperrposition zum zweiten Mal aufgerufen. Wenn ein Deadlock auftritt, bedeutet dies, dass die Sperre nicht wiedereintrittsfähig ist. (In der Sperrfunktion sollten Sie überprüfen, ob der Thread der Thread ist, der die Sperre erhalten hat.)
2. Wenn Problem 1 gelöst wurde, ist die Sperre beim ersten Aufruf von unlock() freigegeben. Eigentlich sollte die Sperre nicht aufgehoben werden.
(Zählzeiten für Statistiken nutzen)
Nach der Änderung lautet es wie folgt:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse SpinLock1 {
private AtomicReference<Thread>owner =new AtomicReference<>();
private int count =0;
public void lock(){
Thread current = Thread.currentThread();
if(current==owner.get()) {
count++;
zurückkehren ;
}
while(!owner.compareAndSet(null, current)){
}
}
public void unlock (){
Thread current = Thread.currentThread();
if(current==owner.get()){
if(count!=0){
zählen--;
}anders{
owner.compareAndSet(current, null);
}
}
}
}
Bei dieser Spin-Sperre handelt es sich um eine Wiedereintrittssperre.