Java多執行緒 Lock

2021-08-17 19:06:21 字數 3450 閱讀 4534

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...