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.
Sperrschloss
Blockierende Sperren ändern im Gegensatz zu Spin-Sperren den Ausführungsstatus des Threads.
In der JAVA-Umgebung hat Thread Thread die folgenden Zustände:
1. Neuer Staat
2. Bereitschaftszustand
3. Laufstatus
4. Blockierter Zustand
5. Todeszustand
Man kann sagen, dass die Blockierungssperre es dem Thread ermöglicht, in den Blockierungszustand zu gelangen und zu warten, wenn das entsprechende Signal (Weckzeit, Zeit) empfangen wird, und der Thread in den Bereitschaftszustand wechseln kann durch Konkurrenz.
Zu den Methoden in JAVA, die ein-/austreten, den Status blockieren oder blockierende Sperren enthalten können, gehören das synchronisierte Schlüsselwort (unter anderem die Gewichtssperre), ReentrantLock, Object.wait()/notify(), LockSupport.park()/unpart()( juc oft verwendet)
Das Folgende ist ein Beispiel für eine JAVA-Blockierungssperre:
package lock;import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;import java.util.concurrent.locks.LockSupport;public class CLHLock1 { public static class CLHNode { private volatile Thread isLocked; } @SuppressWarnings("unused") private volatile CLHNode tail; private static final ThreadLocal<CLHNode> LOCAL = new ThreadLocal<CLHNode>(); private static final AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class, CLHNode.class, "tail"); public void lock() { CLHNode node = new CLHNode(); .set(node); CLHNode preNode = UPDATER.getAndSet(this, node); if (preNode != null) { preNode.isLocked = Thread.currentThread(); preNode = null; void unlock() { CLHNode node = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock/t" + node.isLocked.getName()); LockSupport.unpark(node.isLocked }}
Hier verwenden wir die Blockierungssperre von LockSupport.unpark(). Dieses Beispiel ist gegenüber der CLH-Sperre modifiziert.
Der Vorteil von Blockierungssperren besteht darin, dass blockierte Threads keine CPU-Zeit beanspruchen und keine übermäßige CPU-Auslastung verursachen. Die Eintrittszeit und Wiederherstellungszeit ist jedoch etwas langsamer als bei Spin-Sperren.
Bei starkem Wettbewerb ist die Leistung von Blocksperren deutlich höher als die von Spinsperren.
Die ideale Situation besteht darin, Spin-Sperren zu verwenden, wenn die Thread-Konkurrenz nicht groß ist, und blockierende Sperren, wenn die Konkurrenz groß ist.
(Volltext endet)