多線程編程之Lock的使用 學習筆記

Lock的使用

ReentrantLock類:可以和synchronized一樣來實現線程之間的同步互斥,此外,還有:嗅探鎖定。多路分支通知(需要藉助於Condition對象)等功能。比synchronized靈活!

public class MyService {
private Lock lock = new ReentrantLock();
public void testMethod() {

//獲取鎖(獲得同步監視器)
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("ThreadName="+Thread.currentThread().getName()+(" "+(i+1)));
}

//釋放鎖
lock.unlock();
}
}

使用Condition實現等待/通知 :

單個condition

實現多路通知功能:在一個Lock對象裏面,可以創建多個Condition(對象監視器)實例,線程對象可以註冊在指定的Condition中。從而可以有選擇性的進行線程通知,在 調度線程上更加靈活!等待:Condition condition = new lock.newCondition();  condition.await();通知 condition.signal();

N個condition

運行過程中,可能出現假死,解決方案:把signalAll()修改成signalAll()

PS:公平鎖和不公平鎖。線程獲取鎖的順序是按照線程加鎖的順序來分配的,FIFO先進先出順序,非公平鎖,是隨機獲得鎖,先來的不一定先得到鎖,造成一些可能一直 拿不到鎖,結果就是不公平了 : Lock lock  = new ReentrantLock(isFair);    isFair 是Boolean類型的值!

Method:service.getHoldCount()查詢當前線程保持此鎖定的個數,也就是調用lock()的次數

service.getQueueLength()獲取正在等待獲取此鎖定的 線程估計數 返回值也就是有幾個線程正在等待lock的釋放!

service.getWaitQueueLength(Condition condition):返回等待與此鎖定相關的給定條件Condition的線程估計數!

service.hasQueueThread() 查詢指定的線程是否正在等待獲取此鎖定

service.hasQueueThreads()查詢是否有線程正在等待獲取此鎖定!

lock.hasWaiters(Condition condition):查詢是否有線程正在等待與此鎖定有關的condition條件!

lock.isFair()判斷lock是不是公平鎖

lock.isHeldByCurrentThread()查詢當前線程是否保持此鎖定

lock.isLocked()查詢此鎖定是否有任意線程保持

lock.lockInterruptibly()如果當前線程未被中斷,則獲取鎖定(和lock.lock類似),如果已經中斷(可以調用thread.interrupt主動中斷線程進行測試),則出現異常

lock.tryLock()的作用,僅在調用時,鎖定未被另一個線程保持的鎖定,並獲取該鎖定!

lock.tryLock(long timeout,TimeUnit unit);如果鎖定在給定等待時間內沒有被另一個線程 保持,且當前線程未被中斷,則獲取該鎖定TimeUnit.SECONDS一般爲秒

ReentrantReadWriteLock的使用:讀寫互斥  讀讀共享  寫寫互斥

public void read() {
try {
try {
//lock.readLock().lock();獲取讀鎖
lock.writeLock().lock();
System.out.println("獲寫鎖"+Thread.currentThread().getName()+""+System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.writeLock().unlock();
}
} catch (Exception e) {
e.printStackTrace();

}
 

發佈了45 篇原創文章 · 獲贊 12 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章