2017-04-04 4 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

HashMapを使用する方法

public boolean addKey(String key, String value); 

でシングルトンサービスを使用します第1の解決策は、到来する要求ごとにアレイがコピーされるので、性能の問題を引き起こす可能性がある。

3番目の解決策は優れていますが、組み込みロックはコントローラ/サービス上の静的オブジェクトである必要があります。これはまた、dataに触れるたびにシンクロナイゼーションされたブロックを覚えておく必要があるので、これはおそらく最良の解決策ではありません。

第2の選択肢は、この場合の最善の解決策です。内部にdataを格納するシングルトンを作成し、​​メソッドを提供します。同期のものは1つのクラス内で閉じられます。そのシングルトンラッパーの実装に

私の試みは次のようになります:

//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()を使用することができます。

注:収集されたデータの再生方法はわかりませんが、リスト以外のコレクションを検討してください。特定のデータオカレンスの数が重要でない場合、ListSetHashSetの実装に置き換える方が良いでしょう。 (あなたがdata=test1を2度受け取ったときのように、あなたは何度も何度もtest1が気になっています)。数字について気にするならば、値の写像を出現回数と考えることもできます。

0

私はその後、あなたのサービスでは、私は>

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

質問全体のポイントはスレッドの安全性であり、スレッドセーフではないソリューションを提供しました。 Btw。鍵とは何か、価値は何ですか? –

+0

ああ申し訳ありませんが、あなたはaddメソッドとgetKeyMapにsynchronizedキーワードを追加するだけです。 – cralfaro

+0

これらのキーは "データ"パラメータになり、リストにはすべてのパラメータ値test1、test2、...が格納されます – cralfaro

関連する問題