2013-09-20 6 views
0

В настоящее время у нас есть метод, который считывает данные клиента из нашей базы данных, проверяет данные для некоторых условий, а затем отправляет уведомления по электронной почте на основании того, выполнены ли эти условия.Многопоточность ответа? Обработка большого количества обработки

Этот процесс запускается каждую минуту

Однако, поскольку все больше клиентов будут добавлены к нашей системе, что такой же процесс необходимо повторить для каждого клиента.

Конечно, это не имело бы смысл сделать цикл по каждому клиенту, как так:

 
CUSTOMERS = get_all_customers() 
FOREACH(customer in CUSTOMERS) 
    MyMethod(customer) 
END FOR 

выше кажется очень неэффективным. там

 
CUSTOMERS = get_all_customers() 
FOREACH(customer in CUSTOMERS) 
    StartNewThread(MyMethod(customer)) 
END FOR 

ли какие-либо проблемы с этим:

Я имею в виду многопоточных подход будет работать лучше, как так? В частности, скажем, есть 10 клиентов, тогда я уверен, что все будет хорошо - 10 потоков будут охватывать. Но что происходит, когда есть 50 или 100 клиентов? Это означает, что каждую минуту будут созданы 100 нитей! Каковы мои альтернативы?

+1

Async. Вместо того, чтобы создавать пучок потоков, которые, вероятно, будут сидеть, не делая ничего заблокированного, просто несколько потоков, которые не заблокированы, ждут ввода-вывода и прочее. – vcsjones

+0

, так как есть тег .NET ... Я предполагаю, что вы можете использовать Задачи или напрямую использовать пул потоков и позволить этому обрабатывать много работы для вас по эффективности потоков. В противном случае, если вы всегда создаете больше потоков, чем у вас есть процессоры, вы все равно не получаете какой-либо производительности. – Scott

ответ

0

Необходимо учитывать учетное время/контекст, таким образом, если у вас 1000 пользователей, это будет 1000 потоков, а также время создания потоков. Я предлагаю вам это:

CUSTOMERS = get_all_customers() 
size = CUSTOMERS.size()/1000; 
for (int i = 0; i < size; i++) { 
    StartNewThread(MyMethodOnArray(Array, size*i, size*(i+1) -1)); 
} 

Получить поток для каждого регистра 1k, компенсирующий накладные расходы. Или сделайте это, используйте ThreadPool, статическое количество доступных потоков и попросите каждый поток взять клиентский регистр и использовать синхронизированную функцию, которая возвращает текущий индекс в массиве и увеличивает его на единицу. В Java что-то вроде

int current_client; 
synchronized int getIndex() { 
    int j = current_client; 
    current_client++; 
    if (j < CUSTOMERS.size()) 
     return j; 
    return -1; 
} 

Проверьте -1, если поток получает это, он останавливается.

+0

Спасибо. Итак, для первого метода вы предлагаете последовательно обрабатывать 1000 клиентов в потоке? Итак, '' FOR X = от 1 до 1000 {myMethod()} '' - это то, что будет существовать в потоке? Может ли это вызвать какой-либо процессор? Или это хуже с 1 нитью на метод? – Ricky

+0

Это пример, накладные расходы зависят от количества созданных потоков, помните, что есть системные потоки, а пользовательские потоки и потоки пользователей сопоставляются с системными потоками, и каждому из ваших потоков задано определенное время. Чем больше потоков есть, тем меньше времени у каждого потока есть, и общее время накладных расходов будет, количество оборотов в минуту, что может стать больше, чем фактическое время обработки. Я бы пошел с решением пула потоков, потому что каждая операция «отправки почты» может занимать разные промежутки времени, в зависимости от перегруженности сети и т. Д. – Sinn

Смежные вопросы