xylz,imxylz

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

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

          這個小節(jié)介紹Queue的最后一個工具,也是最強(qiáng)大的一個工具。從名稱上就可以看到此工具的特點(diǎn):雙向并發(fā)阻塞隊列。所謂雙向是指可以從隊列的頭和尾同時操作,并發(fā)只是線程安全的實(shí)現(xiàn),阻塞允許在入隊出隊不滿足條件時掛起線程,這里說的隊列是指支持FIFO/FILO實(shí)現(xiàn)的鏈表。

           

          首先看下LinkedBlockingDeque的數(shù)據(jù)結(jié)構(gòu)。通常情況下從數(shù)據(jù)結(jié)構(gòu)上就能看出這種實(shí)現(xiàn)的優(yōu)缺點(diǎn),這樣就知道如何更好的使用工具了。

          LinkedBlockingDeque類圖

          從數(shù)據(jù)結(jié)構(gòu)和功能需求上可以得到以下結(jié)論:

          1. 要想支持阻塞功能,隊列的容量一定是固定的,否則無法在入隊的時候掛起線程。也就是capacity是final類型的。
          2. 既然是雙向鏈表,每一個結(jié)點(diǎn)就需要前后兩個引用,這樣才能將所有元素串聯(lián)起來,支持雙向遍歷。也即需要prev/next兩個引用。
          3. 雙向鏈表需要頭尾同時操作,所以需要first/last兩個節(jié)點(diǎn),當(dāng)然可以參考LinkedList那樣采用一個節(jié)點(diǎn)的雙向來完成,那樣實(shí)現(xiàn)起來就稍微麻煩點(diǎn)。
          4. 既然要支持阻塞功能,就需要鎖和條件變量來掛起線程。這里使用一個鎖兩個條件變量來完成此功能。

           

          有了上面的結(jié)論再來研究LinkedBlockingDeque的優(yōu)缺點(diǎn)。

          優(yōu)點(diǎn)當(dāng)然是功能足夠強(qiáng)大,同時由于采用一個獨(dú)占鎖,因此實(shí)現(xiàn)起來也比較簡單。所有對隊列的操作都加鎖就可以完成。同時獨(dú)占鎖也能夠很好的支持雙向阻塞的特性。

          凡事有利必有弊。缺點(diǎn)就是由于獨(dú)占鎖,所以不能同時進(jìn)行兩個操作,這樣性能上就大打折扣。從性能的角度講LinkedBlockingDeque要比LinkedBlockingQueue要低很多,比CocurrentLinkedQueue就低更多了,這在高并發(fā)情況下就比較明顯了。

          前面分析足夠多的Queue實(shí)現(xiàn)后,LinkedBlockingDeque的原理和實(shí)現(xiàn)就不值得一提了,無非是在獨(dú)占鎖下對一個鏈表的普通操作。

          有趣的是此類支持序列化,但是Node并不支持序列化,因此fist/last就不能序列化,那么如何完成序列化/反序列化過程呢?

          清單1 LinkedBlockingDeque的序列化、反序列化

          private void writeObject(java.io.ObjectOutputStream s)
              throws java.io.IOException {
              lock.lock();
              try {
                  // Write out capacity and any hidden stuff
                  s.defaultWriteObject();
                  // Write out all elements in the proper order.
                  for (Node<E> p = first; p != null; p = p.next)
                      s.writeObject(p.item);
                  // Use trailing null as sentinel
                  s.writeObject(null);
              } finally {
                  lock.unlock();
              }
          }

          private void readObject(java.io.ObjectInputStream s)
              throws java.io.IOException, ClassNotFoundException {
              s.defaultReadObject();
              count = 0;
              first = null;
              last = null;
              // Read in all elements and place in queue
              for (;;) {
                  E item = (E)s.readObject();
                  if (item == null)
                      break;
                  add(item);
              }
          }

           

          清單1 描述的是LinkedBlockingDeque序列化/反序列化的過程。序列化時將真正的元素寫入輸出流,最后還寫入了一個null。讀取的時候?qū)⑺袑ο罅斜碜x出來,如果讀取到一個null就表示結(jié)束。這就是為什么寫入的時候?qū)懭胍粋€null的原因,因?yàn)闆]有將count寫入流,所以就靠null來表示結(jié)束,省一個整數(shù)空間。

           



          ©2009-2014 IMXYLZ |求賢若渴
          posted on 2010-08-18 16:01 imxylz 閱讀(9770) 評論(5)  編輯  收藏 所屬分類: Java Concurrency

          評論

          # re: 深入淺出 Java Concurrency (25): 并發(fā)容器 part 10 雙向并發(fā)阻塞隊列 BlockingDeque[未登錄] 2010-08-19 16:25 行云流水
          樓主走神了,這么久來更新一次。哈哈  回復(fù)  更多評論
            

          # re: 深入淺出 Java Concurrency (25): 并發(fā)容器 part 10 雙向并發(fā)阻塞隊列 BlockingDeque[未登錄] 2010-11-16 16:38 蟲蟲
          樓主怎么不繼續(xù)拉,想看啊~  回復(fù)  更多評論
            

          # re: 深入淺出 Java Concurrency (25): 并發(fā)容器 part 10 雙向并發(fā)阻塞隊列 BlockingDeque 2011-02-15 10:46 hixiaomin
          最底部導(dǎo)航有些小問題,哈哈。  回復(fù)  更多評論
            

          # re: 深入淺出 Java Concurrency (25): 并發(fā)容器 part 10 雙向并發(fā)阻塞隊列 BlockingDeque 2011-02-15 10:51 xylz
          @hixiaomin
          你真仔細(xì),贊!  回復(fù)  更多評論
            

          # re: 深入淺出 Java Concurrency (25): 并發(fā)容器 part 10 雙向并發(fā)阻塞隊列 BlockingDeque[未登錄] 2016-04-22 15:19
          Mark,今天看到這里啦,滿滿的成就感。。。。。嘿嘿  回復(fù)  更多評論
            


          ©2009-2014 IMXYLZ
          主站蜘蛛池模板: 囊谦县| 揭阳市| 垦利县| 安康市| 砚山县| 芦溪县| 西宁市| 东港市| 佛山市| 伽师县| 镇原县| 海宁市| 共和县| 泽库县| 达日县| 青铜峡市| 昌黎县| 右玉县| 南和县| 隆德县| 张掖市| 遂溪县| 鸡西市| 潼关县| 奉化市| 邮箱| 吴旗县| 龙州县| 介休市| 浦北县| 吴桥县| 松滋市| 徐水县| 孟州市| 比如县| 营口市| 静安区| 万安县| 沾化县| 京山县| 来凤县|