reentrantlock可以和synchronized達到一樣的效果,並且擴充套件功能上也更加強大,而且使用更加靈活。
lock
lock=new reentrantlock();
//加鎖
lock.lock();
//取消鎖
lock.unlock();
等待通知模式:
synchronized與wait()和notify方法結合可以實現等待通知模式
wait():釋放占有的物件鎖,執行緒進入等待池,釋放cpu,而其他正在等待的執行緒即可搶占此鎖,獲得鎖的執行緒即可執行程式。而sleep()不同的是,執行緒呼叫此方法後,會休眠一段時間,休眠期間,會暫時釋放cpu,但並不釋放物件鎖。也就是說,在休眠期間,其他執行緒依然無法進入此**內部。休眠結束,執行緒重新獲得cpu,執行**。wait()和sleep()最大的不同在於wait()會釋放物件鎖,而sleep()不會!
notify(): 該方法會喚醒因為呼叫物件的wait()而等待的執行緒,其實就是對物件鎖的喚醒,從而使得wait()的執行緒可以有機會獲取物件鎖。呼叫notify()後,並不會立即釋放鎖,而是繼續執行當前**,直到synchronized中的**全部執行完畢,才會釋放物件鎖。jvm則會在等待的執行緒中排程乙個執行緒去獲得物件鎖,執行**
1個執行緒訪問a的**,拿到obj的鎖,但是執行了obj.wait()馬上就釋放了obj的鎖
這時候另乙個拿到obj鎖進入b的**,但是執行了obj.notify(),通知等待的執行緒準備啟動
//a
synchronized (obj)
//bsynchronized (obj)
reentrantlock可可以實現同樣的功能。而且更加靈活,可以實現選擇性通知。
lock lock=new reentrantlock();
condition condition = lock.newcondition();
try catch (interruptedexception e) finally
// 釋放
// condition.signal();
執行結果為:顯示a,然後執行緒處於waiting狀態
注意: condition.await();必須在lock()範圍內,不然會報異常。
object類的wait(),相當於condition的await();
object類的wait(long timeout),相當於condition的await(long time,timeunit unit);
object類的notify(),相當於condition的signal();
object類的notifyall(),相當於condition的signalall();
多個condition
condition conditiona = lock.newcondition();
condition conditionb = lock.newcondition();
conditiona 只能喚醒conditiona 的await(),也就是每個condition 都是單獨隔離的
公平鎖,非公平鎖:
公平鎖表示執行緒獲取鎖的順序是按照執行緒加鎖的順序來分配的(lock.lock()順序),即先來的先得到。
非公平鎖是乙個鎖的搶占機制,是隨機獲取鎖,可能造成某些執行緒一直拿不到鎖。
//公平鎖
lock lock=new reentrantlock(true);
//非公平鎖
lock lock=new reentrantlock(false);
//預設非公平鎖
lock lock=new reentrantlock();
方法
//查詢當前執行緒保持鎖定的個數,就是呼叫lock()方法次數
lock.getholdcount();
//返回正等待獲取此鎖定的執行緒估計數
lock.getqueuelength();
//返回等待與此鎖定相關的給定條件condition的執行緒估計數
lock.getwaitqueuelength(condition);
//查詢指定的執行緒是否正在等待此鎖
lock.hasqueuedthread(thread);
//查詢是否有執行緒正在等等此鎖
lock.hasqueuedthreads();
//查詢是否有執行緒正在等待此鎖定有關的condition條件
lock.haswaiters(condition);
//是否是公平鎖
lock.isfair();
//查詢當前執行緒是否保持鎖
lock.isheldbycurrentthread();
//查詢此鎖是否由任意的執行緒保持
lock.islocked();
//如果當前執行緒未被中斷,則獲取鎖定,如果已經被中斷則出現異常
lock.lockinterruptibly();
//僅在呼叫時鎖未被其他執行緒鎖定的情況下,才獲取該鎖。
lock.trylock();
//鎖定在給等待時間內沒有被另乙個執行緒保持,且當前執行緒未被中斷,則獲取該鎖定。
lock.trylock(long timeout,timeunit unit);
reentrantlock具有完全互斥的效果,同乙個時間只有乙個執行緒在執行lock()方法後面的內容,保證了例項變數的執行緒安全性。但是效率比較低下。
reentrantreadwritelock讀寫鎖,有兩個鎖。乙個是讀操作相關的鎖,也叫做共享鎖;另乙個是寫操作的相關的鎖,也叫做排他鎖。(1)也就是多個讀鎖間不互斥;(2)讀鎖寫鎖互斥;(3)寫鎖寫鎖互斥。
在沒有執行緒thread進入寫入操作時,進行讀取操作的多個thread都可以讀取讀鎖,而進入寫入操作的thread只有在獲取寫鎖後才能進行寫入操作。即多個thread可以同時進行讀取操作,但是同一時刻只允許乙個thread進行寫入操作
reentrantreadwritelock lock=new reentrantreadwritelock();
lock.readlock().lock();
lock.writelock().lock();
過程:
「讀寫」、「寫讀」、「寫寫」,互斥
當乙個執行緒已經獲得了讀鎖,而且還沒釋放正在執行,這時候有乙個執行緒要獲取寫鎖,則等待。
當乙個執行緒已經獲得了寫鎖,而且還沒釋放正在執行,這時候有乙個執行緒要獲取讀鎖,則等待。
當乙個執行緒已經獲得了寫鎖,而且還沒釋放正在執行,這時候有乙個執行緒要獲取寫鎖,則等待。
「讀讀」,不互斥
當多個執行緒都想要獲得乙個讀鎖時,發現沒有其他執行緒擁有寫鎖,則執行
多執行緒 Lock
reentrantlock和synchronized區別 作用跟synchronized 鎖一樣 reentrantlock 底層是 cas 值,期望,預期 synchronized 底層鎖公升級 reentrantlock 可以trylock 嘗試鎖 a.如果在某時間段內獲取到鎖,就執行 b.如果...
Java 多執行緒之Lock的用法
lock 為執行緒加鎖解鎖,因為多個執行緒在訪問同乙個資源時,乙個資源不能同時給兩個執行緒進行讀寫操作.所以使用執行緒同步的方式來對資源進行訪問限制.下面來看lock的用法 使用流程 1.建立reentrantlock物件,首先,這個reentrantlock類 重入鎖 是一種遞迴無阻塞的同步機制的...
java 9多執行緒Lock鎖
雖然我們可以理解同步 塊和同步方法的鎖物件問題,但是我們並沒有直接看到在 加上了鎖,在 釋放了鎖,為了更清晰的表達如何加鎖和釋放鎖,jdk5以後提供了乙個新的鎖物件lock。lock是個介面。public class sellticket implements runnable catch inte...