1、科普定義java
這篇博文的兩個主角「synchronized」和「讀寫鎖」面試
1)synchronized數據庫
這個同步關鍵字相信你們都用得比較多,在上一篇「多個線程之間共享數據的方式」中也詳細列舉他的應用,在這就很少說只作幾點概括:編程
2)讀寫鎖緩存
咱們對數據的操做無非兩種:「讀」和「寫」,試想一個這樣的情景,當十個線程同時讀取某個數據時,這個操做應不該該加同步。答案是不必的。只有如下兩種狀況須要加同步:多線程
因此性能
java5提供了讀寫鎖這種鎖支持多線程讀操做不互斥,多線程讀寫互斥,多線程寫寫互斥。讀操做不互斥這樣有助於性能的提升,這點在java5之前沒有優化
二.用一道面試題來具體比較這兩點ui
題目:「白板編程,實現一個緩存系統」spa
題目分析:
對這個緩存系統的理解:
間於用戶和數據庫中間的一個環節,咱們知道用戶直接訪問數據庫的時間是遠大於直接訪問內存,因此有了緩存區後用戶訪問數據時 這樣,用戶先訪問緩存區當緩存區有用戶須要的數據時直接拿走,當緩存區沒有這樣的數據,訪問數據庫並把訪問所得的數據放在緩存區,這樣當下一個須要這個數據的用戶就直接訪問內存便可獲得。
核心代碼實現:
首先用synchronized實現
public synchronized Object getData(String key){ Object result = map.get(key); if(result ==null){ result = "new";//用這步代替訪問數據庫得數據 } return result; }
用讀寫鎖實現
public Object getData(String key){ rw.readLock().lock();//在讀前先上讀鎖 Object result = null; try{ result = map.get(key); //這個if比較關鍵,它避免了多餘的幾回對數據哭的讀取 if(result==null){ //若是內存中沒有所要數據 rw.readLock().unlock(); rw.writeLock().lock(); if(result==null){ try{ //咱們用這個代替對數據庫訪問獲得數據的步驟 result = "new"; }finally{ rw.writeLock().unlock(); } rw.readLock().lock(); } } }finally{ rw.readLock().unlock(); } return result; }
代碼分析:
class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); <span style="color: #ff0000;">if (!cacheValid)</span> { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); // Recheck state because another thread might have acquired // write lock and changed state before we did. <span style="color: #ff0000;"> if (!cacheValid)</span> { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); rwl.writeLock().unlock(); // Unlock write, still hold read } use(data); rwl.readLock().unlock(); } }