鎖的重入是指同一個線程能夠屢次獲取同一個鎖,synchronize是隱式的可重入鎖,ReentrantLock經過代碼實現了鎖的重入:
final boolean nofairTryAcquire(int acquires){ final Thread current=Thread.currentThread(); int c=getState(); if(c==0){ if(compareAndSetState(0,acquires)){ setExclusiveOwnerThread(current); return true; } }else if(current==getExclusiveOwnerThread()){ int nextc=c+acquires; if(nextc<0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
從上面的代碼中,能夠一目瞭然的發現,當獲取鎖的線程與擁有鎖的線程是同一個線程時,僅會對狀態進行累加。so easy ,並無什麼難度。那接下來咱們想一下,如何實現公平所和非公平鎖,上面的代碼是非公平鎖的實現方式。那如何實現公平鎖那?所謂的公平鎖就是全部獲取鎖的線程都要按照「先來後到」的順序獲取鎖。假設線程B在阻塞隊列中,等待獲取鎖,若是還有一個線程A在B的前面,那麼B就要讓A先獲取鎖。所以在B嘗試獲取鎖以前,只要判斷一下它是否還有前驅的隊列便可。很easy吧:ui
final boolean fairTryAcquire(int acquires){ final Thread current=Thread.currentThread(); int c=getState(); if(c==0){ if(!hasQueuedPredecessors()&&compareAndSetState(0,acquires)){//判斷是否有前驅線程等待獲取鎖 setExclusiveOwnerThread(current); return true; } }else if(current==getExclusiveOwnerThread()){ int nextc=c+acquires; if(nextc<0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
公平所和非公平鎖的各自優點是什麼那?公平鎖很好理解,能夠防止出現線程飢餓現象,每個線程都有機會獲取到鎖。非公平鎖可能會致使線程飢餓,可是咱們通常使用非公平鎖,由於非公平鎖能夠減小上下文的切換,提升效率。線程