Весь смысл Java EE состоит в том, чтобы включить в инфраструктуру общие архитектурные проблемы, такие как безопасность, состояние и параллелизм, и позволить вам предоставить кусочки бизнес-логики или сопоставления данных вместе с проводкой для их соединения. Таким образом, Java EE преднамеренно скрывает неприятные моменты параллелизма (блокировки для изменяемого состояния чтения / записи) в структуре.
Такой подход позволяет гораздо более широкому кругу разработчиков успешно писать правильные приложения. Однако необходимым побочным эффектом является то, что эти абстракции создают накладные расходы и снимают контроль. Это и хорошо (делать это простым и кодировать политики как политики, а не кодировать) и плохо (если вы знаете, что делаете, и можете сделать выбор невозможным в рамках).
Нет ничего плохого в том, чтобы на производственной коробке было 80 потоков. Большинство будет заблокировано или ожидает ввода / вывода, что нормально. Существует (настраиваемый) пул потоков, выполняющих фактические вычисления, и Java EE предоставит вам внешние ловушки для настройки этих ручек.
Актеры - другая модель. Они также позволяют вам писать островки кода (тело актера), которые (могут) избегать блокировок для изменения состояния. Вы можете написать, что ваши акторы не сохраняют состояние (фиксируя состояние в параметрах рекурсивного вызова функции) или полностью скрываете свое состояние в экземпляре актора, чтобы все состояние было ограничено (для актеров стиля реакции вам, вероятно, все еще нужно явно ограничить доступ к данным обеспечить видимость в следующем потоке, который запускает ваш актер).
Я не могу сказать, что одно или другое лучше. Я думаю, что есть достаточное доказательство того, что обе модели могут использоваться для написания безопасных, высокопроизводительных систем. Для того чтобы любой из них работал хорошо, вам нужно серьезно подумать о своей проблеме и создать приложения, которые изолируют части состояния и вычисления для каждого вида состояния. Для кода, где вы хорошо понимаете свои данные и обладаете высоким потенциалом параллелизма, я думаю, что модели вне Java EE имеют большой смысл.
Как правило, при определении размеров связанных с вычислениями пулов потоков необходимо, чтобы они были приблизительно равны N ядер + 2. Многие фреймворки автоматически устанавливают размер. Вы можете использовать Runtime.getRuntime (). AvailableProcessors (), чтобы получить N. Если ваша проблема разлагается в алгоритме стиля «разделяй и властвуй» и количество элементов данных велико, я настоятельно рекомендую проверить функцию fork / join, которая может быть теперь используется как отдельная библиотека и будет частью Java 7.
Что касается того, как управлять этим, вы не должны порождать потоки как таковые внутри Java EE (они хотят это контролировать), но вы могли бы исследовать отправку запроса в ваш поток потоков, обрабатывающий данные, через очередь сообщений и обработка этого запроса с помощью сообщения возврата. Это может вписаться в модель Java EE (конечно, немного неуклюже).
У меня есть список актеров, fork / join и некоторые другие модели параллелизма, которые могут вас заинтересовать: http://tech.puredanger.com/2011/01/14/comparing-concurrent-frameworks/