2017-04-04 62 views
2

我有用於如URL:我怎樣才能捕捉請求數據在靜態列表

http://some_url.suffix?data=test1. 

我將有排序的多個請求:

http://some_url.suffix?data=test1 
http://some_url.suffix?data=test2 
http://some_url.suffix?data=test3 
http://some_url.suffix?data=test4 

我希望保持服務器端的靜態列表,其中將包含從所有會話請求接收的數據

List<String> data; 

列表將包含data1,d ATA2,DATA3,DATA4。列表將在特定時間間隔後被清除,新列表將用於後續請求。 什麼是實現這一目標的最佳選擇:

1. static List<String> data = new CopyOnWriteArrayList<String>(); 
2. Singleton wrapper class to perform operation on normal java.util.List 
3. using synchronized block 
+0

'data.add(request.getParameter('data'))'? –

+0

這是很明顯的,但我想知道最好的方式,即靜態聲明的數據或其他東西。 – dpanshu

+0

如何從客戶端發送數據時聲明數據?如果您知道數據是什麼,則無需從客戶端獲取數據,如果您不知道該數據,則必須從請求中獲取數據。 –

回答

0

第一種解決方案可能會導致性能問題,因爲數組將在每個傳入請求上被複制。

第三種解決方案比較好,只要記住固有鎖應該也是控制器/服務上的靜態對象。這也需要每次觸摸data時記住同步塊,因此這可能不是最佳解決方案。

第二種選擇是針對該情況的最佳解決方案。創建內部存儲data的單身人士,並提供​​方法來玩它。同步內容將在一個類中關閉。

我試圖實現,單包裝的將是這樣的:

//Use enum to have singleton provided by jvm 
enum DataCache { 

    INSTANCE; 

    //Use LinkedList if you expecting many calls. The insertion will be much faster. 
    private List<String> data = new LinkedList<>(); 

    synchronized void add(String value) { 
     data.add(value); 
    } 

    /* 
    * Returns defensive copy, so that no one has reference to this.data. 
    * If data is fetched only on clear you can make this private instead of synchronized 
    * (or even better get rid of it and create defensive copy inside clear()). 
    */ 
    synchronized List<String> get() { 
     return new ArrayList<>(data); 
    } 

    /* 
    * Returns last snapshot of data to keep consistency. 
    */ 
    synchronized List<String> clear() { 
     List<String> lastSnapshot = get(); 
     data = new LinkedList<>(); 
     return lastSnapshot; 
    } 
} 

然後你就可以在該處理的調度請求,並INSTANCE.clear()方法使用INSTANCE.add()

注意我不知道你如何玩收集的數據,但考慮其他收集比列表。如果特定數據事件的數量並不重要,則最好將List替換爲SetHashSet的實現。 (就像你兩次收到data=test1一樣,你只關心測試1出現了多少次)。如果你關心數字,你也可以考慮將數值映射到出現次數。

0

我會用一個單獨服務與方法

public boolean addKey(String key, String value); 

然後在你的服務,我會用一個HashMap>

private static Map<String, List<String>> keysMap; 

private Map<String, List<String>> getKeysMap(){ 
    synchronized (this){   
     if(keysMap == null){ 
      keysMap = new HashMap(); 
     } 
     return keysMap; 
    } 
} 

public void addKey(String key, String value){ 
    List<String> keyParams = getKeysMap().get(key); 
    if(keyParams == null){ 
     keyParams = new ArrayList(); 
    } 
    //decide here if you want to store repeated values 
    keyParams.add(param); 
    getKeysMap().put(key, keyParams); 
} 
+0

問題的全部內容是線程安全的,您提供的解決方案根本不是線程安全的。順便說一句。什麼是關鍵,什麼是價值? –

+0

啊對不起,我忘記了,你只需要添加synchronized關鍵字添加方法和getKeyMap。 – cralfaro

+0

它們的鍵將是你的「數據」參數,並且該列表將存儲所有你的參數值test1,test2,... – cralfaro