1.阻塞鎖spa
多個線程同時調用同一個方法的時候,全部線程都被排隊處理了。讓線程進入阻塞狀態進行等待,當得到相應的信號(喚醒,時間) 時,才能夠進入線程的準備就緒狀態,準備就緒狀態的全部線程,經過競爭,進入運行狀態。
線程
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等對反應時間要求很高的系統來講,這是不可行的,所以須要讓其非阻塞,能夠在沒有拿到鎖以後立刻返回,告訴客戶稍後重試。code
2.非阻塞鎖blog
多個線程同時調用一個方法的時候,當某一個線程最早獲取到鎖,這時其餘線程判斷沒拿到鎖,這時就直接返回,只有當最早獲取到鎖的線程釋放,其餘線程才能進來,在它釋放以前其它線程都會獲取失敗。ip
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.自旋鎖和互斥鎖資源
當一個線程在獲取鎖的時候,若是鎖已經被其它線程獲取,那麼該線程將循環等待,而後不斷的判斷鎖是否可以被成功獲取,直到獲取到鎖纔會退出循環。get
獲取鎖的線程一直處於活躍狀態,因爲一直調用while循環,可是並無執行任何有效的任務,使用這種鎖會形成busy-waiting。同步
互斥鎖也是爲了保護共享資源的同步,在任什麼時候刻,最多隻能有一個保持者,也就說,在任什麼時候刻最多隻能有一個執行單元得到鎖。可是二者在調度機制上略有不一樣。對於互斥鎖,若是資源已經被佔用,資源申請者只能進入睡眠狀態。可是自旋鎖不會引發調用者睡眠,若是自旋鎖已經被別的執行單元保持,調用者就一直循環在那裏看是否該自旋鎖的保持者已經釋放了鎖。it
//自旋鎖
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(); } }