AQS之工做原理

前面一章LZ簡單的介紹了下AbstractQueuedSynchronizer(AQS)以及AQS中提供的一些模板方法和做用,這一章LZ將用一個簡單的實例來介紹下AQS中獨佔鎖的工做原理。獨佔鎖顧名思義就是在同一時刻只能有一個線程能獲取到鎖,而其它須要獲取這把鎖的線程將進入到同步隊列中等待獲取到了鎖的線程釋放這把鎖,只有獲取鎖的線程釋放了鎖,同步隊列中的線程才能獲取鎖。LZ能夠描述的有些繞,畫圖來解釋下這段話的意思:java

AQS原理

這個圖則清晰的說明了AQS中獨佔鎖的的基本原理,下面LZ將用一段簡單的代碼來看看AQS中獨佔鎖的工做原理。面試

public class ExclusiveDemo implements Lock {    
    // 靜態內部類,自定義同步器    
    private static class Sync extends AbstractQueuedSynchronizer{        
        // 是否處於獨佔狀態        
        @Override        
        protected boolean isHeldExclusively() {            
            return this.getState() == 1;        
        }        
        // 當狀態爲0時,獲取鎖        
        @Override        
        protected boolean tryAcquire(int arg) {           
            if(compareAndSetState(0,1)){                
                setExclusiveOwnerThread(Thread.currentThread());                
                return true;            
            }           
            return false;      
        }        
        // 釋放鎖,將狀態設置爲0        
        @Override        
        protected boolean tryRelease(int arg) {           
            if(getState() == 0) throw new IllegalMonitorStateException();                       
            setExclusiveOwnerThread(null);            
            setState(0);            
            return true;        
        }        
        // 返回一個Condition,沒給Condition都包含了一個Condition隊列        
        Condition newCondition() {            
            return new ConditionObject();       
        }   
    }    
    private final Sync sync = new Sync();    
    @Override    
    public void lock() {        
        sync.acquire(1);   
    }   
    @Override    
    public void lockInterruptibly() throws InterruptedException {        
        sync.acquireInterruptibly(1);    
    }   
    @Override    
    public boolean tryLock() {        
        return sync.tryAcquire(1);    
    }    
    @Override    
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {   
        return sync.tryAcquireSharedNanos(1,unit.toNanos(time));   
    }   
    @Override   
    public void unlock() {       
        sync.release(0);   
    }    
    @Override   
    public Condition newCondition() {      
        return sync.newCondition();    
    }
}

上面示例中,獨佔所ExclusiveDemo是一個自定義的同步組件,它在同一時刻只容許一個線程佔有鎖。ExclusiveDemo定義了一個靜態內部類,該內部類繼承了同步器並實現了獨佔式獲取和釋放同步狀態。在tryAcquire方法中,經過CAS方式設置同步器狀態,若是設置成功,返回true,設置失敗返回false。tryRelease(int arg)方法是將同步器狀態設置爲0。經過上面的示例,我麼能夠看到,當咱們在使用ExclusiveDemo的時候,咱們並無直接和同步器打交道,而是經過調用ExclusiveDemo提供的方法。這一章LZ只是簡單的介紹了下AQS是如何工做的,下一章LZ分析下AQS中CHL的工做原理。ide


關注下面公衆號,回覆 1024 領取最新大廠面試資料ui

相關文章
相關標籤/搜索