<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    xylz,imxylz

    關(guān)注后端架構(gòu)、中間件、分布式和并發(fā)編程

       :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      111 隨筆 :: 10 文章 :: 2680 評(píng)論 :: 0 Trackbacks

    可以在對(duì)中對(duì)元素進(jìn)行配對(duì)和交換的線程的同步點(diǎn)。每個(gè)線程將條目上的某個(gè)方法呈現(xiàn)給 exchange 方法,與伙伴線程進(jìn)行匹配,并且在返回時(shí)接收其伙伴的對(duì)象。Exchanger 可能被視為 SynchronousQueue 的雙向形式。

    換句話說(shuō)Exchanger提供的是一個(gè)交換服務(wù),允許原子性的交換兩個(gè)(多個(gè))對(duì)象,但同時(shí)只有一對(duì)才會(huì)成功。先看一個(gè)簡(jiǎn)單的實(shí)例模型。

     

    Exchanger

    在上面的模型中,我們假定一個(gè)空的棧(Stack),棧頂(Top)當(dāng)然是沒(méi)有元素的。同時(shí)我們假定一個(gè)數(shù)據(jù)結(jié)構(gòu)Node,包含一個(gè)要交換的元素E和一個(gè)要填充的“洞”Node。這時(shí)線程T1攜帶節(jié)點(diǎn)node1進(jìn)入棧(cas_push),當(dāng)然這是CAS操作,這樣棧頂就不為空了。線程T2攜帶節(jié)點(diǎn)node2進(jìn)入棧,發(fā)現(xiàn)棧里面已經(jīng)有元素了node1,同時(shí)發(fā)現(xiàn)node1的hold(Node)為空,于是將自己(node2)填充到node1的hold中(cas_fill)。然后將元素node1從棧中彈出(cas_take)。這樣線程T1就得到了node1.hold.item也就是node2的元素e2,線程T2就得到了node1.item也就是e1,從而達(dá)到了交換的目的。

    算法描述就是下圖展示的內(nèi)容。

    image

    JDK 5就是采用類(lèi)似的思想實(shí)現(xiàn)的Exchanger。JDK 6以后為了支持多線程多對(duì)象同時(shí)Exchanger了就進(jìn)行了改造(為了支持更好的并發(fā)),采用ConcurrentHashMap的思想,將Stack分割成很多的片段(或者說(shuō)插槽Slot),線程Id(Thread.getId())hash相同的落在同一個(gè)Slot上,這樣在默認(rèn)32個(gè)Slot上就有很好的吞吐量。當(dāng)然會(huì)根據(jù)機(jī)器CPU內(nèi)核的數(shù)量有一定的優(yōu)化,有興趣的可以去了解下Exchanger的源碼。

    至于Exchanger的使用,在JDK文檔上有個(gè)例子,講述的是兩個(gè)線程交換數(shù)據(jù)緩沖區(qū)的例子(實(shí)際上仍然可以認(rèn)為是生產(chǎn)者/消費(fèi)者模型)。

    class FillAndEmpty {
       Exchanger
    <DataBuffer> exchanger = new Exchanger<DataBuffer>();
       DataBuffer initialEmptyBuffer
    =  a made-up type
       DataBuffer initialFullBuffer
    = 

      
    class FillingLoop implements Runnable {
        
    public void run() {
           DataBuffer currentBuffer
    = initialEmptyBuffer;
          
    try {
            
    while (currentBuffer != null) {
               addToBuffer(currentBuffer);
              
    if (currentBuffer.isFull())
                 currentBuffer
    = exchanger.exchange(currentBuffer);
             }
           }
    catch (InterruptedException ex) { handle }
         }
       }

      
    class EmptyingLoop implements Runnable {
        
    public void run() {
           DataBuffer currentBuffer
    = initialFullBuffer;
          
    try {
            
    while (currentBuffer != null) {
               takeFromBuffer(currentBuffer);
              
    if (currentBuffer.isEmpty())
                 currentBuffer
    = exchanger.exchange(currentBuffer);
             }
           }
    catch (InterruptedException ex) { handle }
         }
       }

      
    void start() {
        
    new Thread(new FillingLoop()).start();
        
    new Thread(new EmptyingLoop()).start();
       }
      }

     

    Exchanger實(shí)現(xiàn)的是一種數(shù)據(jù)分片的思想,這在大數(shù)據(jù)情況下將數(shù)據(jù)分成一定的片段并且多線程執(zhí)行的情況下有一定的使用價(jià)值。

    最近一直推托工作忙,更新頻度越來(lái)越低了,好在現(xiàn)在的工作還有點(diǎn)個(gè)人時(shí)間,以后爭(zhēng)取多更新下吧,至少也要把這個(gè)專(zhuān)輯寫(xiě)完。

     



    ©2009-2014 IMXYLZ |求賢若渴
    posted on 2010-11-22 22:31 imxylz 閱讀(7748) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Java Concurrency

    ©2009-2014 IMXYLZ
    主站蜘蛛池模板: 亚洲情A成黄在线观看动漫软件| 国产精品亚洲αv天堂无码| 最新黄色免费网站| 亚欧免费一级毛片| 久久精品私人影院免费看| 久久久久久AV无码免费网站下载 | 亚洲色丰满少妇高潮18p| 亚洲欧洲日韩极速播放| 亚洲熟女综合色一区二区三区 | 亚洲精品色午夜无码专区日韩| 亚洲伊人久久成综合人影院| 日韩亚洲变态另类中文| 国产亚洲无线码一区二区| 亚洲A∨无码无在线观看| 亚洲精品美女视频| 亚洲综合伊人制服丝袜美腿| 亚洲色欲啪啪久久WWW综合网| 亚洲妇女无套内射精| 免费人成再在线观看网站 | 精品丝袜国产自在线拍亚洲| 亚洲日韩精品国产3区| 无码色偷偷亚洲国内自拍| 免费一级毛片在线播放放视频| 两性色午夜免费视频| 久久国产精品国产自线拍免费| 最近中文字幕mv免费高清在线| 国产又黄又爽又猛免费app| 妞干网免费视频观看| 亚洲成aⅴ人片久青草影院 | 毛片在线免费视频| 四虎影视永久免费观看网址| 久久亚洲高清综合| 久久99亚洲网美利坚合众国| 亚洲精品人成网在线播放影院| 香港一级毛片免费看| 国内精品久久久久影院免费| 国产高清免费视频| 亚洲成年看片在线观看| 亚洲国产香蕉碰碰人人| 亚洲国产精华液2020| 丁香花在线视频观看免费|