Расширяясь в приведенных определениях, самое главное, что вам нужно знать как веб-разработчик, заключается в том, что NO STATE SAVED между postbacks. Есть способы сохранить состояние, например коллекции Session или Viewstate в ASP.NET, но, как правило, пишите свои программы, где вы можете воссоздать свое состояние при каждой обратной передаче.
Это, вероятно, самый большой разница между настольным и веб-программированием приложений и заняла у меня месяцы, чтобы узнать, до чего я инстинктивно писал этот путь.
Не та же задача, но «да» - очередь обычно используется в критических по времени задачах. Мы сконцентрировались на том, чтобы избежать синхронизации для обработки событий вообще. Просмотрите следующие советы
«Допустимая задержка» полностью зависит от вашего приложения. Работа со всем в одном потоке действительно может помочь, если у вас очень строгие требования к задержке. К счастью, у большинства приложений нет таких строгих требований.
Конечно, если только один поток может получать запросов, то привязка этого потока к вычислению ответа будет означать, что вы не сможете принимать никакие другие запросы. В зависимости от того, что вы делаете, вы можете использовать асинхронный ввод-вывод (и т. Д.), Чтобы избежать модели «поток на запрос», но это значительно сложнее IMO и все равно заканчивается переключением контекста потока.
Иногда уместно ставить запросы в очередь, чтобы не обрабатывать их слишком большим количеством потоков: если ваша обработка привязана к ЦП, не имеет большого смысла иметь сотни потоков - лучше иметь очередь задач производителя / потребителя и распределить их примерно по одному потоку на ядро. Это в основном то, что будет делать ThreadPoolExecutor
, если вы, конечно, правильно его настроите. Это также не работает, если ваши запросы проводят много времени в ожидании внешних служб (включая диски, но в первую очередь другие сетевые службы) ... в этот момент вам либо нужно использовать асинхронные модели выполнения, когда вы потенциально можете сделать ядро простаивает с блокирующим вызовом, или вы принимаете попадание переключения контекста потока и имеете много потоков, полагаясь на планировщик потоков, чтобы он работал достаточно хорошо.
Суть в том, что требования к задержке могут быть жесткими - по моему опыту, они значительно жестче, чем требования к пропускной способности, поскольку их намного сложнее масштабировать. Однако это действительно зависит от контекста.
Есть ли причина, по которой вы не используете LinkedBlockingQueue
, чтобы ваш производитель мог поставить в очередь пару элементов вместо SynchronousQueue
? По крайней мере, есть очередь с 1 элементом в ней, чтобы вы могли получить лучший параллелизм.
Какова скорость процесса «подготовки» по сравнению с «ответом»? Можно ли использовать пул потоков, чтобы несколько потоков обрабатывали ответы, если они слишком дороги?
50us звучит несколько завышенно для передачи обслуживания, IME (Solaris 10 / Opteron) LBQ обычно находится в диапазоне 30-35us, в то время как LTQ ( LinkedTransferQueue
) составляет около 5us быстрее, чем это. Как указано в других ответах SynchronousQueue
может быть немного медленнее, потому что предложение не возвращается, пока другой поток не займет его.
Согласно моим результатам, Solaris 10 заметно медленнее, чем Linux, в котором время меньше 10 мкс.
Это действительно зависит от нескольких вещей: при пиковой нагрузке
Если вы знаете ответ на эти вопросы Qs, то с точки зрения производительности должно быть довольно ясно, следует ли обрабатывать в принимающем потоке или передавать обслуживание потоку обработки.