Lock ist ein Tool, das den Zugriff mehrerer Threads auf gemeinsam genutzte Ressourcen steuert. Normalerweise bietet eine Sperre exklusiven Zugriff auf eine gemeinsam genutzte Ressource. Es kann jeweils nur ein Thread eine Sperre erwerben, und jeder Zugriff auf eine gemeinsam genutzte Ressource erfordert zunächst den Erwerb der Sperre. Einige Sperren ermöglichen jedoch möglicherweise den gleichzeitigen Zugriff auf gemeinsam genutzte Ressourcen, z. B. ReadWriteLock (eine Lese-/Schreibsperre, die ein Paar zusammengehöriger Sperren aufrechterhält, eine für schreibgeschützte Vorgänge und die andere für Schreibvorgänge).
1. Lock bietet bedingungslose, abrufbare, zeitgesteuerte und unterbrechbare Sperrenerfassungsvorgänge. Alle Sperr- und Entsperrmethoden sind explizit.
public interface Lock{ void lock(); //加锁 //优先考虑响应中断,而不是响应锁定的普通获取或重入获取 void lockInterruptibly() throws InterruptedException; boolean tryLock(); //可定时和可轮询的锁获取模式 boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException; void unlock(); //解锁 Condition newCondition(); }
2. ReentrantLock implementiert die Sperrschnittstelle. Im Vergleich zu synchronisiert bietet ReentrantLock mehr Flexibilität bei der Handhabung nicht verfügbarer Sperren.
3. Die kanonische Form der Verwendung der Sperrschnittstelle erfordert die Freigabe der Sperre lock.unlock() im Finally-Block. Wenn der Code, der die Sperre schützt, eine Ausnahme außerhalb des Try-Blocks auslöst, wird diese niemals freigegeben.
Das Folgende simuliert die Verwendung von Sperren: Angenommen, es gibt zwei Threads (A-Thread, B-Thread), um die print(String-Name)-Methode aufzurufen. Ein Thread ist für das Drucken der Zeichenfolge „zhangsan“ verantwortlich, und Thread B ist dafür verantwortlich Verantwortlich für das Drucken der Zeichenfolge „lisi“.
1. Wenn die Methode print(String name) nicht gesperrt ist, kommt es vor, dass Thread A die Ausführung nicht abgeschlossen hat und Thread B mit der Ausführung begonnen hat. Dann treten beim gedruckten Namen die folgenden Probleme auf.
2. Wenn der Methode print(String name) eine Sperre hinzugefügt wird, führt Thread B die Methode print(String name) erst aus, nachdem A die Ausführung abgeschlossen hat, um einen gegenseitigen Ausschluss- oder Synchronisationseffekt zu erzielen.
package com.ljq.test.thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 用Lock替代synchronized * * @author Administrator * */ public class LockTest { public static void main(String[] args) { new LockTest().init(); } private void init() { final Outputer outputer = new Outputer(); //A线程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output("zhangsan"); } } }).start(); //B线程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output("lisi"); } } }).start(); } static class Outputer { Lock lock = new ReentrantLock(); /** * 打印字符 * * @param name */ public void output(String name) { int len = name.length(); lock.lock(); try { for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } finally { lock.unlock(); } } } }
Weitere Artikel zu Beispielen für die Verwendung von Sperren in der Java-Multithread-Programmierung finden Sie auf der chinesischen PHP-Website!