日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > ReentrantReadWriteLock讀寫鎖的使用2

ReentrantReadWriteLock讀寫鎖的使用2

來源:程序員人生   發布時間:2015-02-03 08:40:39 閱讀次數:3288次

本文可作為傳智播客《張孝祥-Java多線程與并發庫高級利用》的學習筆記。

這1節我們做1個緩存系統。


在讀本節前
請先瀏覽
ReentrantReadWriteLock讀寫鎖的使用1

初版

public class CacheDemo { private Map<String, Object> cache = new HashMap<String, Object>(); public static void main(String[] args) { CacheDemo cd = new CacheDemo(); System.out.println("ss "+cd.getData2("ss")); System.out.println("ss "+cd.getData2("ss")); System.out.println("mm "+cd.getData2("mm")); System.out.println("mm "+cd.getData2("mm")); } public Object getData2(String key){ Object o=cache.get(key); if (o==null) { //標識1 System.out.println("第1次查 沒有"+key); o=Math.random(); //實際上從數據庫中取得 cache.put(key, o); } return o; } }
運行結果:
第1次查  沒有ss
ss   0.4045014284225158
ss   0.4045014284225158
第1次查  沒有mm
mm   0.9994663041529088
mm   0.9994663041529088

似乎沒有問題。
你覺得呢?
如果有3個線程同時第1次到了getData2()的標識1處(所查找的key也都1樣),1檢查o為null,然后就去查數據庫。在這類情況下,就等于3個線程查同1個key,然后都去了數據庫
這明顯是不公道的。

第2版 synchronized

最簡單的辦法
    public synchronized Object getData2(String key){
        //.....

    }


第3版 鎖

上1節我們提到了ReentrantLock可以替換synchronized,前者是1種更加面向對象的設計。那我們試試。
private Lock l=new ReentrantLock(); //l作為CacheDemo的成員變量 public Object getData3(String key) { l.lock(); Object o=null; try { o = cache.get(key); if (o == null) { // 標識1 System.out.println("第1次查 沒有" + key); o = Math.random(); // 實際上從數據庫中取得 cache.put(key, o); } } finally { l.unlock(); } return o; }
第3版可以嗎?
可以個p。

為何,自己想。


我們得使用ReentrantReadWriteLock,在同1個方法中既有讀鎖也有寫鎖。

首先我又1個問題:

對同1個線程,可以在加了讀鎖后,沒有解開讀鎖前,再加寫鎖嗎?

換句話說,下面的代碼會停嗎?

public class CacheDemo { private Map<String, Object> cache = new HashMap<String, Object>(); private ReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { CacheDemo cd = new CacheDemo(); cd.getData2(); } public void getData2(){ rwl.readLock().lock(); System.out.println(1); rwl.writeLock().lock(); System.out.println(2); rwl.readLock().unlock(); System.out.println(3); rwl.writeLock().unlock(); System.out.println(4); } }
親身試1下,控制臺輸出1后,程序就不動了。

說明加寫鎖前,讀鎖得先解開。

第4版

即有讀鎖,又有寫鎖
   
public static void main(String[] args) { CacheDemo cd = new CacheDemo(); System.out.println("ss "+cd.getData4("ss")); System.out.println("ss "+cd.getData4("ss")); System.out.println("mm "+cd.getData4("mm")); System.out.println("mm "+cd.getData4("mm")); } public Object getData4(String key){ rwl.readLock().lock(); Object o=null; try { o=cache.get(key); if (o==null) { System.out.println("第1次查 沒有"+key); rwl.readLock().unlock(); //標識4 rwl.writeLock().lock(); try { if(value==null){ //標識0 value = "aaaa";//實際調用 queryDB(); cache.put(key,value); } } finally { rwl.writeLock().unlock(); } rwl.readLock().lock(); //標識1 } }finally { rwl.readLock().unlock(); //標注2 } return o; }
結果
第1次查  沒有ss
ss   0.5989899889645358
ss   0.5989899889645358
第1次查  沒有mm
mm   0.8534424949014686

mm   0.8534424949014686

這個還有3個問題

1為何在標識2處還得解鎖。
這個答案在上1節已提過。

2為何在標識1出還得加鎖?
如果標識1處不加鎖,且程序1直正常履行,那末到標識2處,它解誰的鎖?


3為何標識0出還要檢查1次?
如果同時又3個線程運行到標識4(查找相同的key),其中1個取得寫鎖,寫入數據后,釋放了寫鎖。此時另外兩個線程還需要去數據庫跑1趟么?

另外把標識1處的加讀鎖,放到finally的前面稱之為降級鎖。對降級鎖,我目前也不太清楚。
官方文檔中給了1個例子就是關于降級鎖,以下
class CachedData { Object data; volatile boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }

感謝glt




生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 91亚洲国产 | 欧美日韩在线一区 | 欧美做受| 成人性生交大片免费看中文 | 久久久久一区二区三区 | 久久久久综合 | www一区| 黄网站在线免费看 | 亚洲精品久久久久久久久久久 | 国产欧美日本 | av网站免费在线观看 | 一级毛片免费播放 | 99re久久 | 日韩欧美高清视频 | 欧美一区亚洲一区 | 亚洲精品2 | a亚洲天堂 | 成人永久aaa | 91精品国产91久久综合 | 九色最新网址 | 黄色国产大片 | 欧美日本久久 | 黄色毛片小视频 | 在线国产一区二区 | 亚洲精品国产视频 | 精品九九九九九 | 国产精品一区二区av日韩在线 | 久久一区二| 国产伦精品一区二区三区免费视频 | 欧美一二三区 | 男女污污 | 毛片无码国产 | 国产欧美精品一区二区 | 亚洲a人 | 91香蕉视频好色先生 | 国产成人免费视频 | 国产精品久久久久久久免费软件 | 青青国产精品 | 日韩视频一区二区 | 国产成人免费视频 | 欧美视频网站 |