0

一部のサーバーからのネットワークアクティビティデータを保存するプログラムがあります。速度を上げるために、各リクエストを個別のスレッドで実行し、結果を汎用ディクショナリに配置するようにアプリケーションを設計します。ここで、キーはサーバーIDであり、オブジェクトは結果クラスです。

ただし、サーバーからのこの応答は、10分ごとにDBに保存する必要があります。これを解決するための良いアイデアがあるかどうかはわかりません。したがって、いくつかの入力は素晴らしいでしょう。

私が念頭に置いているのは、結果ディクショナリをロックして結果のディープクローンを作成し、DBに配置した別のスレッドで結果の分析を開始することです。

request threadsからのブロックを最小限に抑えて、新しい結果をできるだけ早く追加し始めても、辞書から読み取ることができるようにするにはどうすればよいですか?

4

2 に答える 2

2

アイデアは、新しい入力を新しいストレージに送信しながら、永続化ロジックが起動するまでの間、現在の状態を脇に置くことです。これは、このタスクの基本的なパターンです。

class PeriodicPersist{

    // Map must be volatile, persist may look at a stale copy
    private volatile Map<String, String> keyToResultMap = new HashMap<String, String>();

    public  void newResult(String key, String result) {
        synchronized(keyToResultMap) {  // Will not enter if in the beginning of persist
            keyToResultMap.put(key,result);
        }
    }

    public void persist(){
        Map<String, String> tempMap;
        synchronized (keyToResultMap) { // will not enter if a new result is being added just now.
            if(keyToResultMap.size() == 0) {
                return;
            }

            tempMap = keyToResultMap;
            keyToResultMap = new HashMap<String, String>();
        }

        // download freshMap to the DB OUTSIDE the lock
    }
}
于 2013-02-10T19:39:26.187 に答える
1

ConcurrentDictionaryを使用すると、辞書のロックに対処する必要がなくなります。ディクショナリのコンテンツをチェックして現在のカウントアイテムをDBに保存し、同じものを削除してから、保存されたコンテンツの分析を開始するタイマーベースのイベントを使用して、10分ごとにスレッドを実行します。

// myCD is your concurrent dictionary
// every 10 mins
var myCDClone = myCD.MemberwiseClone();
// save to DB using myCDClone 
// using myCDClone.Keys delete everything saved up from myCD
// myCDClone.Clear();
于 2013-02-10T18:15:31.390 に答える