0

我有一个程序可以存储来自某些服务器的一些网络活动数据。为了速度,我将设计应用程序以在单独的线程中发出每个请求,并将结果放入通用字典中,其中键是服务器 ID,对象是结果类。

但是,来自服务器的响应应该每 10 分钟保存一次到 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避免处理锁定字典。使用基于计时器的事件每 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 回答