激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 舉例說明Java多線程編程中讀寫鎖的使用

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

2021-11-12 17:12YangYiBao Java教程

這篇文章主要介紹了舉例說明Java多線程編程中讀寫鎖的使用,文中的例子很好地說明了Java的自帶讀寫鎖ReentrantReadWriteLock的使用,需要的朋友可以參考下

以下示例為 java api并發(fā)庫中 ReentrantReadWriteLock自帶的實(shí)例,下面進(jìn)行解讀

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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();
 }
}

當(dāng)有n多線程 使用同一CachedData 實(shí)例對(duì)象 調(diào)用processCachedData方法時(shí),就會(huì)產(chǎn)生線程的并發(fā)問題.
@1行,當(dāng)有線程正在對(duì)數(shù)據(jù)進(jìn)行 寫操作的時(shí)候,運(yùn)行到@1行的線程要等待 寫操作的完成,因?yàn)榈谝粋€(gè)運(yùn)行到@2的線程會(huì)加上鎖,然后對(duì)數(shù)據(jù)進(jìn)行需該,期間不允許任何線程進(jìn)行讀或者是寫的操作,

當(dāng)寫完后,在該線程上加上讀鎖操作,以防止解寫鎖后,別的線程對(duì)數(shù)據(jù)再次進(jìn)行寫時(shí)出錯(cuò).在第一個(gè)運(yùn)行到@2的線程之后的很多線程,

可能已經(jīng)運(yùn)行到了@4,當(dāng)對(duì)數(shù)據(jù)修改好之后,解除掉寫鎖,別的線程就會(huì)執(zhí)行到@2,這時(shí)第一個(gè)線程已經(jīng)經(jīng)數(shù)據(jù)修改好了,所以有了@3的判斷。

在編寫多線程程序的時(shí)候,要置于并發(fā)線程的環(huán)境下考慮,巧妙的運(yùn)用ReentrantReadWriteLock,在運(yùn)用時(shí),注意鎖的降級(jí),寫入鎖可以獲得讀鎖,讀鎖不可以獲得寫入鎖,所以在上寫入鎖時(shí),必須先將讀鎖進(jìn)行解除,然后上讀鎖。

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

?
1
2
3
4
rwl.writeLock().lock();
//在寫鎖狀態(tài)中,可以獲取讀鎖
rwl.readLock().lock();
rwl.writeLock().unlock();

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

?
1
2
3
4
5
rwl.readLock().lock();
//......
//必須釋放掉讀鎖,才能夠加寫鎖
rwl.readLock().unlock();
rwl.writeLock().lock();

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

謹(jǐn)在此附上我自己寫的緩存系統(tǒng)的簡(jiǎn)單實(shí)現(xiàn),你從中也能悟出緩存實(shí)現(xiàn)的基本思想

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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;
/**
 * 緩存的實(shí)現(xiàn),每個(gè)線程只能獲得他自己的緩存,也應(yīng)該是單例的
 * 本類沒有去實(shí)現(xiàn)單例,如果需要的話可以自行去實(shí)現(xiàn)
 * @author scl
 *
 */
public class CacheSystem {
  private Map<String, Object> cache = new HashMap<String,Object>();
  private ReadWriteLock rwl = new ReentrantReadWriteLock();
  public Object getData(String key){
    //先從緩存中去取數(shù)據(jù),先加上讀鎖 
    rwl.readLock().lock();
    Object obj = null;
    try{
      obj = cache.get(key);
      if(obj == null){
        //先解除讀鎖,在上寫鎖(必須先解除讀鎖才能成功上寫鎖) 
        rwl.readLock().unlock();
        rwl.writeLock().lock();
        //去數(shù)據(jù)庫取數(shù)據(jù),再判斷一次是否為null,因?yàn)橛锌赡芏鄠€(gè)線程獲得寫鎖 
        try{
        if(obj == null){
          obj = new String("obj is get from db");
        }
        }finally{
          //先上讀鎖,然后再解除寫鎖(這樣可以成功完成,在解除寫鎖前獲得讀鎖,寫鎖被降級(jí)--這翻譯的api上的) 
          rwl.readLock().lock();
          rwl.writeLock().unlock();//解除寫鎖,讀鎖仍然持有 
        }
      }
    }finally{
      rwl.readLock().unlock();
    }
    return obj;
  }
 
}

延伸 · 閱讀

精彩推薦
  • Java教程xml與Java對(duì)象的轉(zhuǎn)換詳解

    xml與Java對(duì)象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對(duì)象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程升級(jí)IDEA后Lombok不能使用的解決方法

    升級(jí)IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級(jí),尋思已經(jīng)有好久沒有升過級(jí)了。升級(jí)完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對(duì)java開發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對(duì)于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
主站蜘蛛池模板: 久久久久久久免费看 | 成人性视频欧美一区二区三区 | 看免费一级毛片 | 性少妇videosexfreexx | 久久不射电影网 | 久久精品国产清自在天天线 | 国产精品一区在线观看 | 美女wc| 免费一级片观看 | 日日草天天干 | 国产一区二区三区四区在线 | 强伦女教师视频 | 91羞羞| 一级成人欧美一区在线观看 | 久草导航 | 国产精品久久久久久影院8一贰佰 | 青草av.久久免费一区 | 日本在线精品视频 | 国产噜噜噜噜久久久久久久久 | 亚洲一区成人在线 | 国产亚洲精品久久久闺蜜 | 国产精品久久77777 | 久久精品视频免费 | 国产乱淫av片免费观看 | 国产精品视频久 | 国产一级免费在线视频 | 国产精品成人一区二区三区电影毛片 | 国产毛毛片一区二区三区四区 | 欧美日韩国产综合网 | 免费看毛片网站 | 鸥美一级片 | 日韩激情一区二区三区 | japanesexxxxxxxhd | 欧美激情猛片xxxⅹ大3 | 欧美性生交xxxxx免费观看 | 国产九九九九 | 国产精品久久久免费观看 | 天天操天天操天天操天天操天天操天天操 | 九九精品免费 | 香蕉久久久精品 | 日韩深夜视频 |