中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Java多線(xian)程:CopyOnWrite容器

一、什么是CopyOnWrite容器

CopyOnWrite容(rong)(rong)(rong)器(qi)即寫時(shi)復(fu)制(zhi)的(de)容(rong)(rong)(rong)器(qi)。通俗的(de)理解是(shi)當(dang)(dang)(dang)我們往(wang)一(yi)個(ge)(ge)容(rong)(rong)(rong)器(qi)添(tian)加元(yuan)素的(de)時(shi)候,不直(zhi)接往(wang)當(dang)(dang)(dang)前(qian)容(rong)(rong)(rong)器(qi)添(tian)加,而是(shi)先將(jiang)(jiang)當(dang)(dang)(dang)前(qian)容(rong)(rong)(rong)器(qi)進(jin)行Copy,復(fu)制(zhi)出一(yi)個(ge)(ge)新(xin)的(de)容(rong)(rong)(rong)器(qi),然(ran)后(hou)新(xin)的(de)容(rong)(rong)(rong)器(qi)里添(tian)加元(yuan)素,添(tian)加完元(yuan)素之(zhi)后(hou),再將(jiang)(jiang)原容(rong)(rong)(rong)器(qi)的(de)引用指向新(xin)的(de)容(rong)(rong)(rong)器(qi)。這樣做的(de)好(hao)處是(shi)我們可以對CopyOnWrite容(rong)(rong)(rong)器(qi)進(jin)行并發(fa)的(de)讀,而不需要加鎖,因為當(dang)(dang)(dang)前(qian)容(rong)(rong)(rong)器(qi)不會添(tian)加任何元(yuan)素。所以CopyOnWrite容(rong)(rong)(rong)器(qi)也(ye)是(shi)一(yi)種(zhong)讀寫分離的(de)思想(xiang),讀和寫不同的(de)容(rong)(rong)(rong)器(qi)。
 

二、CopyOnWriteArrayList的實現原理

在使用CopyOnWriteArrayList之前(qian),我們先閱讀其源碼了(le)解(jie)下它是如(ru)何實(shi)現的。以(yi)下代(dai)碼是向(xiang)ArrayList里添(tian)加(jia)元素,可以(yi)發現在添(tian)加(jia)的時候是需要加(jia)鎖的,否則多(duo)線(xian)程寫的時候會Copy出N個副本出來。
public boolean add(T e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        // 復制出新(xin)數組
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 把新元素(su)添加到新數組里
        newElements[len] = e;
        // 把原數(shu)組引用(yong)指(zhi)向新數(shu)組
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}
 
final void setArray(Object[] a) {
    array = a;
}

 

讀(du)的(de)時(shi)候(hou)不需(xu)要加鎖(suo),如果讀(du)的(de)時(shi)候(hou)有多(duo)個(ge)線程(cheng)正(zheng)在向ArrayList添(tian)加數據,讀(du)還是會讀(du)到舊的(de)數據,因為寫的(de)時(shi)候(hou)不會鎖(suo)住舊的(de)ArrayList。
 

三(san)、CopyOnWrite的應用場景

CopyOnWrite并發容器用于讀多寫(xie)少的(de)并發場景(jing)。比如(ru)白名(ming)單,黑名(ming)單,商品類目的(de)訪問和更新場景(jing),假如(ru)我們(men)有一個(ge)搜(sou)索(suo)(suo)(suo)網(wang)站,用戶(hu)在(zai)(zai)這個(ge)網(wang)站的(de)搜(sou)索(suo)(suo)(suo)框中(zhong)(zhong),輸(shu)入關(guan)鍵字搜(sou)索(suo)(suo)(suo)內容,但(dan)是某些(xie)關(guan)鍵字不(bu)允(yun)許被搜(sou)索(suo)(suo)(suo)。這些(xie)不(bu)能(neng)被搜(sou)索(suo)(suo)(suo)的(de)關(guan)鍵字會被放在(zai)(zai)一個(ge)黑名(ming)單當(dang)中(zhong)(zhong),黑名(ming)單每(mei)天晚上(shang)更新一次。當(dang)用戶(hu)搜(sou)索(suo)(suo)(suo)時,會檢(jian)查當(dang)前關(guan)鍵字在(zai)(zai)不(bu)在(zai)(zai)黑名(ming)單當(dang)中(zhong)(zhong),如(ru)果在(zai)(zai),則提(ti)示不(bu)能(neng)搜(sou)索(suo)(suo)(suo)。
 
代碼(ma)很(hen)簡(jian)單,但是使用(yong)CopyOnWriteMap需要(yao)注(zhu)意兩(liang)件事情:
  1. 減少擴容開銷。根據實際需要,初始化CopyOnWriteMap的(de)大小,避免寫時CopyOnWriteMap擴容的(de)開銷。
  2. 使用(yong)批量添加(jia)(jia)(jia)。因為每次添加(jia)(jia)(jia),容器每次都會進行復制(zhi),所以減(jian)少(shao)添加(jia)(jia)(jia)次數(shu),可以減(jian)少(shao)容器的復制(zhi)次數(shu)。如(ru)使用(yong)上面代碼里的addBlackList方法(fa)。
 

四(si)、CopyOnWrite的缺點

CopyOnWrite容器有很多優點,但是同(tong)時也存在兩個問題,即(ji)內存占用(yong)問題和(he)數據一(yi)致性問題。所以在開發的(de)時候需要注(zhu)意一(yi)下(xia)。
  • 內(nei)存(cun)(cun)占(zhan)用(yong)(yong)(yong)(yong)問題:因為CopyOnWrite的(de)寫(xie)時(shi)(shi)復(fu)制(zhi)機制(zhi),所以在(zai)(zai)進(jin)(jin)行寫(xie)操作的(de)時(shi)(shi)候,內(nei)存(cun)(cun)里(li)會同時(shi)(shi)駐扎兩個(ge)對(dui)象(xiang)(xiang)的(de)內(nei)存(cun)(cun),舊(jiu)(jiu)的(de)對(dui)象(xiang)(xiang)和(he)新寫(xie)入的(de)對(dui)象(xiang)(xiang)(注意(yi):在(zai)(zai)復(fu)制(zhi)的(de)時(shi)(shi)候只是(shi)復(fu)制(zhi)容(rong)(rong)器(qi)里(li)的(de)引用(yong)(yong)(yong)(yong),只是(shi)在(zai)(zai)寫(xie)的(de)時(shi)(shi)候會創建(jian)新對(dui)象(xiang)(xiang)添加到新容(rong)(rong)器(qi)里(li),而(er)舊(jiu)(jiu)容(rong)(rong)器(qi)的(de)對(dui)象(xiang)(xiang)還在(zai)(zai)使用(yong)(yong)(yong)(yong),所以有(you)兩份對(dui)象(xiang)(xiang)內(nei)存(cun)(cun))。如果這(zhe)些對(dui)象(xiang)(xiang)占(zhan)用(yong)(yong)(yong)(yong)的(de)內(nei)存(cun)(cun)比(bi)較大(da),比(bi)如說200M左右,那(nei)么再(zai)寫(xie)入100M數據進(jin)(jin)去,內(nei)存(cun)(cun)就會占(zhan)用(yong)(yong)(yong)(yong)300M,那(nei)么這(zhe)個(ge)時(shi)(shi)候很有(you)可(ke)能(neng)造(zao)成(cheng)頻繁(fan)的(de)Yong GC和(he)Full GC。之前我們系(xi)統中(zhong)使用(yong)(yong)(yong)(yong)了(le)(le)一個(ge)服務由(you)于每晚(wan)使用(yong)(yong)(yong)(yong)CopyOnWrite機制(zhi)更(geng)新大(da)對(dui)象(xiang)(xiang),造(zao)成(cheng)了(le)(le)每晚(wan)15秒(miao)的(de)Full GC,應用(yong)(yong)(yong)(yong)響應時(shi)(shi)間也(ye)隨之變(bian)長。針對內(nei)存占用問題,可以(yi)通過壓縮容器中(zhong)的元素(su)的方法來減少大(da)對象的內(nei)存消耗(hao),比如(ru),如(ru)果元素(su)全是10進(jin)制(zhi)(zhi)的數字(zi),可以(yi)考慮把它壓縮成36進(jin)制(zhi)(zhi)或64進(jin)制(zhi)(zhi)。或者不使用CopyOnWrite容器,而(er)使用其他的并(bing)發容器,如(ru)。
  • 數(shu)(shu)據(ju)一(yi)致性問題:CopyOnWrite容(rong)器只能保(bao)證數(shu)(shu)據(ju)的最終(zhong)一(yi)致性,不(bu)能保(bao)證數(shu)(shu)據(ju)的實時(shi)一(yi)致性。所以如果你希(xi)望寫入的數(shu)(shu)據(ju),馬上能讀到,請不(bu)要(yao)使用CopyOnWrite容(rong)器。
 
 

參考(kao)資料(liao):

 
 
 
 
 
 
 
 
 
 
 
 
 
 

posted @ 2017-09-28 16:55  ^_TONY_^  閱讀(676)  評論(0)    收藏  舉報