国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

舉例說明Java多線程編程中讀寫鎖的使用

2020-01-24 01:16:56
字體:
來源:轉載
供稿:網友

以下示例為 java api并發庫中 ReentrantReadWriteLock自帶的實例,下面進行解讀

 class CachedData {  Object data;  volatile boolean cacheValid;  ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();  void processCachedData() {   rwl.readLock().lock();//@1   if (!cacheValid) {    // Must release read lock before acquiring write lock    rwl.readLock().unlock();//@4    rwl.writeLock().lock();//@2    // Recheck state because another thread might have acquired    //  write lock and changed state before we did.    if (!cacheValid) {//@3     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();  } }

當有n多線程 使用同一CachedData 實例對象 調用processCachedData方法時,就會產生線程的并發問題.
@1行,當有線程正在對數據進行 寫操作的時候,運行到@1行的線程要等待 寫操作的完成,因為第一個運行到@2的線程會加上鎖,然后對數據進行需該,期間不允許任何線程進行讀或者是寫的操作,

當寫完后,在該線程上加上讀鎖操作,以防止解寫鎖后,別的線程對數據再次進行寫時出錯.在第一個運行到@2的線程之后的很多線程,

可能已經運行到了@4,當對數據修改好之后,解除掉寫鎖,別的線程就會執行到@2,這時第一個線程已經經數據修改好了,所以有了@3的判斷。

在編寫多線程程序的時候,要置于并發線程的環境下考慮,巧妙的運用ReentrantReadWriteLock,在運用時,注意鎖的降級,寫入鎖可以獲得讀鎖,讀鎖不可以獲得寫入鎖,所以在上寫入鎖時,必須先將讀鎖進行解除,然后上讀鎖。

使用時注意的幾個方面:
    讀鎖是排寫鎖操作的,讀鎖不排讀鎖操作,多個讀鎖可以并發不阻塞。即在讀鎖獲取后和讀鎖釋放之前,寫鎖并不能被任何線程獲得,
      多個讀鎖同時作用期間,試圖獲取寫鎖的線程都處于等待狀態,當最后一個讀鎖釋放后,試圖獲取寫鎖的線程才有機會獲取寫鎖。
    寫鎖是排寫鎖、排讀鎖操作的。當一個線程獲取到寫鎖之后,其他試圖獲取寫鎖和試圖獲取讀鎖的線程都處于等待狀態,直到寫鎖被釋放。
      寫鎖是可以獲得讀鎖的,即:

      rwl.writeLock().lock();      //在寫鎖狀態中,可以獲取讀鎖      rwl.readLock().lock();      rwl.writeLock().unlock();

  讀鎖是不能夠獲得寫鎖的,如果要加寫鎖,本線程必須釋放所持有的讀鎖,即:

      rwl.readLock().lock();      //......      //必須釋放掉讀鎖,才能夠加寫鎖      rwl.readLock().unlock();      rwl.writeLock().lock();

讀寫鎖是線程讀寫同一文件所需要用到的,讀寫鎖是什么東西在這里不做過多的解釋,可以自己去百度或谷歌去搜一下。

謹在此附上我自己寫的緩存系統的簡單實現,你從中也能悟出緩存實現的基本思想

緩存里面有數據就從緩存中取,沒有就給你從其他地方得到。

package cn.com.scl.cache  import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /**  * 緩存的實現,每個線程只能獲得他自己的緩存,也應該是單例的  * 本類沒有去實現單例,如果需要的話可以自行去實現  * @author scl  *  */ public class CacheSystem {   private Map<String, Object> cache = new HashMap<String,Object>();   private ReadWriteLock rwl = new ReentrantReadWriteLock();   public Object getData(String key){     //先從緩存中去取數據,先加上讀鎖      rwl.readLock().lock();     Object obj = null;     try{       obj = cache.get(key);       if(obj == null){         //先解除讀鎖,在上寫鎖(必須先解除讀鎖才能成功上寫鎖)          rwl.readLock().unlock();         rwl.writeLock().lock();         //去數據庫取數據,再判斷一次是否為null,因為有可能多個線程獲得寫鎖          try{         if(obj == null){           obj = new String("obj is get from db");         }         }finally{           //先上讀鎖,然后再解除寫鎖(這樣可以成功完成,在解除寫鎖前獲得讀鎖,寫鎖被降級--這翻譯的api上的)            rwl.readLock().lock();           rwl.writeLock().unlock();//解除寫鎖,讀鎖仍然持有          }       }     }finally{       rwl.readLock().unlock();     }     return obj;   }  } 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西城区| 兰坪| 枣强县| 资阳市| 南乐县| 永济市| 巢湖市| 禄丰县| 绥江县| 芜湖市| 喀喇| 会昌县| 论坛| 栖霞市| 临汾市| 电白县| 武清区| 上栗县| 新野县| 毕节市| 鲁甸县| 远安县| 建湖县| 乐平市| 界首市| 杭州市| 临洮县| 清丰县| 霍城县| 迭部县| 贵阳市| 平度市| 葫芦岛市| 台南县| 泸州市| 泰顺县| 岳西县| 中山市| 拉孜县| 邓州市| 台南县|