Recentemente tive uma dúvida sobre a implementação de alguns processos multi-thread em um sistema web da empresa.
O próprio container (Tomcat no nosso caso) possui várias threads, e por isso pensei se criar métodos ou processos que criem outras threads não terá um impacto negativo na performance do sistema.
Tudo bem que os servidores daqui possuem vários processadores com várias threads cada, mas mesmo assim devo pensar em multi-threading apenas para alguns processos mais críticos ou isso não influi na performance?
Servidores web devem ser inerentemente multi-threaded.
O motivo é que eles devem ser capazes de atender vários usuários ao mesmo tempo.
Cada requeisição é tratada por uma determinada Thread. Criar e destruir threads é uma coisa computacionalmente cara, por isso que os containers (incluindo o tomcat) já criam um número razoável de threads no começo e as deixam inativas: para evitar de ter que criá-las ou destruí-las em um momento inoportuno, e para poder reutilizá-las (evitando destruir para depois criar).
Idealmente, você programa de forma que os dados usados em uma thread não sejam compartilhados com outras threads, o que já te dá um multi-threading escalável e robusto. Os problemas começam a surgir quando uma thread tem que fazer alguma coisa que pode influenciar outra thread. É importante minimizar a necessidade de comunicação de threads.
Não há nada de errado por si só em criar threads auxiliares no servidor. No entanto, na maioria das vezes que isso ocorre, é porque o programador fez besteira, fez alguma gambiarra e/ou não sabe direito o que está fazendo, logo isto tende a ser um forte bad-smell.
[quote=victorwss]Servidores web devem ser inerentemente multi-threaded.
O motivo é que eles devem ser capazes de atender vários usuários ao mesmo tempo.
Cada requeisição é tratada por uma determinada Thread. Criar e destruir threads é uma coisa computacionalmente cara, por isso que os containers (incluindo o tomcat) já criam um número razoável de threads no começo e as deixam inativas: para evitar de ter que criá-las ou destruí-las em um momento inoportuno, e para poder reutilizá-las (evitando destruir para depois criar).
Idealmente, você programa de forma que os dados usados em uma thread não sejam compartilhados com outras threads, o que já te dá um multi-threading escalável e robusto. Os problemas começam a surgir quando uma thread tem que fazer alguma coisa que pode influenciar outra thread. É importante minimizar a necessidade de comunicação de threads.
Não há nada de errado por si só em criar threads auxiliares no servidor. No entanto, na maioria das vezes que isso ocorre, é porque o programador fez besteira, fez alguma gambiarra e/ou não sabe direito o que está fazendo, logo isto tende a ser um forte bad-smell.[/quote]
Estou de acodo com tudo dito acima.
Porem existem alguns casos específicos que precisam, ter performace, eu já trabalhei em uma estrutura bem tensa de theads, usando Callable, Pool de threads,BlockingQueue… (Já fico tenso só de lembrar) parecido com os containers dito pelo victors realmente são muito poucos casos que realmente precisa de estrutura assim, fora isso deve ter cuidado pois thread sai caro pro SO separar uma para sua aplicação e na maioria das vezes não compensa.
Você tem que analisar bem se compensa.
Um exemplo que podemos usar varias threads é quando vc tem um belo processamento de dados e existe um tempo de gargalho muito grande de espera de outro processo que vc ñ tem controle, por exemplo socket, webservice. Nestes casos vc consegue separar uma thread para fazer o processamento e a outra trabalhe a comunicação, enfilheirando as tarefas, mais nem sempre é vantajoso.
No Java existe bastante coisa para trabalhar com Thread, mais o interessante e vantajoso é se conseguir usar um pool de threads pois vc tera mais performance do que criar thread manualmente, digamos q vc reutiliza as threads, mais é complexo mexer de uma maneira eficaz com thread, e muito cuidado com as comunicações entre threads.
Pool de threads:
Cabe lembrar que em um ambiente JEE você não deve criar threads manualmente, pois o container é responsável por isso, e ele quem deve criar, e não a aplicação.
Criar outras threads manualmente a partir de uma thread gerenciada por um container geralmente termina em uma bela cagada. Diga o que você quer fazer e provavelmente alguém irá sugerir outra forma de alcançar a performance que você precisa sem ter que meter a mão nesse pote de merda.
Em qualquer abordagem que for usar uma boa estrutura de threads, eu aconselho fazer em um sistema standalone!
E dependendo como for o sistema, adicionaria como serviço do S.O para que fique ativada no momento que eu quero.