您好,登錄后才能下訂單哦!
這篇文章主要介紹java中ReentrantLock類如何使用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
在 Java 多線程中, 可以使用 synchronized 關鍵字來實現多線程之間同步互斥, 但在 JDK 1.5 中新增加了 ReentrantLock 類也能達到同樣的效果, 并且在擴展功能上也更加強大, 比如具有嗅探鎖定, 多路分支通知, 公平鎖和非公平鎖等(默認)功能, 而且在使用上也比 synchronized 更加的靈活.
使用 ReentrantLock 實現同步
public class MyService { private Lock lock = new ReentrantLock(); public void testMethod() { lock.lock(); for (int i = 0; i < 10; i++){ System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1))); } lock.unlock(); } }
public class MyThread extends Thread { private MyService myService; public MyThread(MyService myService) { this.myService = myService; } @Override public void run() { myService.testMethod(); } }
public static void main(String[] args) throws IOException, InterruptedException { MyService myService = new MyService(); MyThread myThreadA = new MyThread(myService); MyThread myThreadB = new MyThread(myService); MyThread myThreadC = new MyThread(myService); MyThread myThreadD = new MyThread(myService); MyThread myThreadE = new MyThread(myService); myThreadA.start(); myThreadB.start(); myThreadC.start(); myThreadD.start(); myThreadE.start(); }
調用 ReentrantLock 對象的 lock() 方法獲取鎖, 調用 unLock() 方法釋放鎖.
從運行結果來看, 當前線程打印完畢之后將鎖進行釋放, 其他的線程才可以繼續打印. 線程打印的數據是分組打印, 因為當前線程已經持有鎖, 但線程之間打印的順序是隨機的.
使用 Condition 實現等待/通知
關鍵字 synchronized 與 wait() 和 notify() / notifyall() 方法結合可以實現等待/通知模式, 只不過在使用時, 調用 notify() 方法 JVM 會隨機選擇一個 WAITNG 狀態的線程來執行.
而使用 Condition 則可以更加靈活, 可以實現 "選擇性通知", 可以指定的選擇喚醒哪些線程, 哪些線程繼續等待.
public class MyService { private Lock lock = new ReentrantLock(); public Condition conditionA = lock.newCondition(); public Condition conditionB = lock.newCondition(); public void awaitA() throws InterruptedException { lock.lock(); System.out.println("begin awaitA 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionA.await(); System.out.println("end awaitA 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); lock.unlock(); } public void awaitB() throws InterruptedException { lock.lock(); System.out.println("begin awaitB 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionB.await(); System.out.println("end awaitB 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); lock.unlock(); } public void signalAll_A() throws InterruptedException { lock.lock(); System.out.println("begin signalAll_A 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionA.signalAll(); lock.unlock(); } public void signalAll_B() throws InterruptedException { lock.lock(); System.out.println("begin signalAll_B 時間" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionB.signalAll(); lock.unlock(); } }
public class ThreadA extends Thread { private MyService myService; public ThreadA(MyService myService) { this.myService = myService; } @Override public void run() { try { myService.awaitA(); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class ThreadB extends Thread { private MyService myService; public ThreadB(MyService myService) { this.myService = myService; } @Override public void run() { try { myService.awaitB(); } catch (InterruptedException e) { e.printStackTrace(); } } }
public static void main(String[] args) throws IOException, InterruptedException { MyService myService = new MyService(); ThreadA threadA = new ThreadA(myService); threadA.setName("a"); threadA.start(); ThreadB threadB = new ThreadB(myService); threadB.setName("b"); threadB.start(); Thread.sleep(3000); myService.signalAll_A(); }
從執行結果來看, a 和 b 線程被暫停, 當執行 myService.signalAll_A() 方法時, a 線程繼續執行, 而 b 線程仍然是等待狀態.
常用方法
ReentrantLock 類
int getHoldCount() 查詢調用 lock() 方法的次數.
final int getQueueLength() 估計等待鎖的線程數. 比如有5個線程, 1個線程首先執行 await() 方法, 那么在調用此方法后返回值是4, 說明有4個線程同時在等待lock的釋放.
int getWaitQueueLength(Condition condition) 返回與此鎖相關聯給定條件等待的線程數的估計. 比如有5個線程, 每個線程都執行了同一個 condition 對象的 await() 方法, 則調用此方法時返回的值是5.
final boolean hasQueuedThreads() 判斷是否有線程等待此鎖.
final boolean hasQueuedThread(Thread thread) 判斷指定線程是否等待獲取此鎖.
boolean hasWaiters(Condition condition) 判斷線程有沒有調用 await() 方法.
void lockInterruptibly() throws InterruptedException 獲取鎖, 除非當前線程為interrupted.
Condition 類
void awaitUninterruptibly() 和 await() 區別就是當調用 interrupt() 方法時不會拋出 InterrputedException 異常.
以上是java中ReentrantLock類如何使用的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。