2012-02-01 88 views
2

我有一個web應用程序,爲每個請求存儲一些信息(例如客戶端ip地址)在一些集合中。有時我需要將它清空,將所有元素序列化爲xml並將xml發送到其他Web服務。我可以爲每個請求創建和發送一個xml,但我寧願發送數據塊(不要與web服務過於頻繁地通信)。我對集合的最大大小沒有要求(除了沒有超出內存的錯誤),必須發送文件的時間以及最小/最大文件大小。有時候jvm崩潰並且我們丟失了存儲在內存中的所有數據也是可以接受的。許多生產者和一個消費者一次輪詢所有消息

我知道許多線程(servlet容器生成的線程)會將元素添加到集合中,並且偶爾一個消費者線程將從集合中獲取所有元素,將它們序列化爲xml併發送文件。你能推薦這個設計嗎?

我應該在消費者線程中使用busy-wait嗎? 哪個線程(生產者或消費者)應該檢查集合大小是否是某個最大/閾值大小? 我可以使用同步集合和生產者端的notifyAll來通知消費者? 我應該在客戶端使用同步和while(大小< MAX){wait()}嗎? 將drainTo比List temp = new ArrayList <>(collection)更好; ?

這是我第一個想法。我敢肯定有很多理由去批評它:

public void add(Info info){ 
    synchronized (collection) { 
     collection.add(info); 
     if (collection.size() > THRESHOLD) { 
      collection.notify(); 
     } 
    } 
} 

public void send(){ 
    while (true) { 
     List<Info> temp = null; 
     synchronized (collection) { 
      try { 
       collection.wait(); 
      } catch (InterruptedException e) { 
      } 
      List<Info> temp = new ArrayList<>(collection); 
      collection.clear(); 
     } 
     serializeAndSend(temp); 
    } 

}

回答

2

不是滾動自己的,至少可以考慮使用類似LinkedBlockingQueuejava.util.concurrent別的東西。

按原樣,您的當前代碼將不起作用,因爲您的notify()wait()調用不適用於同一個對象。

您的需求很有趣。例如,如果JVM死亡(出於任何原因),並且您丟失了所有排隊的數據?無論如何,你的評論 - 你仍然可以做類似於你以前的事情 - 通過自定義方法過濾所有添加操作,並且如果集合達到一定的大小,那麼serializeAndSend。但是,如果遵循這種方法,那麼您確實不需要具有併發支持的集合。我還看到你更新了你的代碼來撥打collection.wait(),這很好。

+0

謝謝,但LinkedBlockingQueue會改變這種情況下的任何事情(只有在預計特定閾值大小時才應該調用take/drainTo)? – user1051075 2012-02-01 12:03:34

+0

@ user1051075 - 請參閱我的答案更新。 (放在那裏,而不是評論,給定長度。) – ziesemer 2012-02-01 13:40:33

相關問題