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();
}
}