2013-02-10 5 views
0

У меня есть программа, которая будет хранить некоторые данные о сетевой активности с некоторых серверов. Для скорости я создам приложение, чтобы сделать каждый запрос в отдельном потоке и поместить результат в общий словарь, где ключ является идентификатором сервера, а объект является классом результатов.Многопоточный дизайн

Однако эти ответы с сервера должны сохраняться каждые 10 минут в БД. Я не знаю, есть ли у меня какая-то хорошая идея, как это решить. Таким образом, какой-то ввод будет отличным.

Что я имею в виду, это заблокировать словарь результатов и сделать глубокий клон результата и начать анализировать результат в другом потоке, который просто поместил его в БД.

Как я могу свести к минимуму блокировку от request threads, чтобы они могли начать добавлять свежие результаты как можно скорее, но все же читать из словаря?

+1

Просто поменяйте словарь на новый. Очень быстро, не забудьте запереть. –

ответ

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(); 
+0

Можно ли клонировать его, даже если в списке нет ни одного безопасного потока, как объект внутри компакт-диска? ConcurrentDictionary > Что делать, если список изменен в тот же момент? –

+0

Отсутствие параллелизма, которое не просачивается ко всем объектам keyvaluepair, просто доступ к словарю. – allen

2

Идея состоит в том, чтобы убрать текущее состояние во времени, когда ваша логика persist срабатывает, направляя новый вход в новое хранилище. Это основной шаблон для этой задачи:

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 
    } 
} 
Смежные вопросы