阻塞鎖,非阻塞鎖,自旋鎖,互斥鎖


1.阻塞鎖

多個線程同時調用同一個方法的時候,所有線程都被排隊處理了。讓線程進入阻塞狀態進行等待,當獲得相應的信號(喚醒,時間) 時,才可以進入線程的准備就緒狀態,准備就緒狀態的所有線程,通過競爭,進入運行狀態。

 

public class Lock{
    private boolean isLocked = false;
    public synchronized void lock() throws InterruptedException{
        while(isLocked){
//當其他線程進來,即處於等待阻塞狀態 wait(); } isLocked
= true; } public synchronized void unlock(){ isLocked = false; notify(); } }

但是由於被調用的方法越耗時,線程越多的時候,等待的線程等待的時間也就越長,甚至於幾分鍾或者幾十分鍾。對於Web等對反應時間要求很高的系統來說,這是不可行的,因此需要讓其非阻塞,可以在沒有拿到鎖之后馬上返回,告訴客戶稍后重試。

2.非阻塞鎖

  多個線程同時調用一個方法的時候,當某一個線程最先獲取到鎖,這時其他線程判斷沒拿到鎖,這時就直接返回,只有當最先獲取到鎖的線程釋放,其他線程才能進來,在它釋放之前其它線程都會獲取失敗。

public class Lock{
    private boolean isLocked = false;
    public synchronized boolean lock() throws InterruptedException{
        if(isLocked){
//當沒有拿到鎖,立即返回,線程不阻塞 return false;
} isLocked = true;

return true; }
public synchronized void unlock(){ isLocked = false; } }

 3.自旋鎖和互斥鎖

當一個線程在獲取鎖的時候,如果鎖已經被其它線程獲取,那么該線程將循環等待,然后不斷的判斷鎖是否能夠被成功獲取,直到獲取到鎖才會退出循環。

獲取鎖的線程一直處於活躍狀態,由於一直調用while循環,但是並沒有執行任何有效的任務,使用這種鎖會造成busy-waiting

互斥鎖也是為了保護共享資源的同步,在任何時刻,最多只能有一個保持者,也就說,在任何時刻最多只能有一個執行單元獲得鎖。但是兩者在調度機制上略有不同。對於互斥鎖,如果資源已經被占用,資源申請者只能進入睡眠狀態。但是自旋鎖不會引起調用者睡眠,如果自旋鎖已經被別的執行單元保持,調用者就一直循環在那里看是否該自旋鎖的保持者已經釋放了鎖。

//自旋鎖
public
class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ sout("繼續不斷的循環來判斷是否可以拿到鎖"); } isLocked = true; } public synchronized void unlock(){ isLocked = false; } }
//互斥鎖
public
class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ //當其他線程進來,直接讓其進入等待狀態,只有當最先拿到鎖的資源,才能繼續執行判斷是否拿到鎖 wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM