Pergunta

Eu tenho um método que será usado para enviar email. Quero bloquear esse método para que apenas um thread possa acessar por tempo e o restante se acumular simultaneamente. Devo sincronizar o método ou usar o Spring @Transaction Propagation_Required?

Na minha camada de serviço

 //each time use new thread to send out email
  public  void sendThroughSMTP(List<String> emails,String subject,String content){

            //each time will open and sent through port 25.  dont u think this will caused too many threads spawned?
            BlastEmailThread blastEmailThread = new BlastEmailThread(emails,subject,content);

            blastEmailThread.start();


}
Foi útil?

Solução

Por que não tornar o tópico do método seguro por não usar nenhuma coisa do nível da instância?

No entanto, não vejo como o gerenciamento de transações da Spring se encaixa aqui. Quero dizer, a primavera fornece poucos gerentes de transação, ou seja, DataSourceTransactionManager, JtaTransactionManager, HibernateTransactionManager Tudo isso é sobre persistência do banco de dados. O que você configurará para este e -mail enviar?

Eu acredito que, primeiro, você deve nos mostrar por que se preocupa com a segurança do fio em primeiro lugar. Provavelmente, você gostaria de nos mostrar algum trecho de código relevante ou algo assim. Então podemos sugerir uma coisa.

Termo aditivo

Quando você está gerando um tópico para cada chamada para esse método e não usando nada do estado, então por que você deseja fazer o método synchronized. Fazer o método sincronizado não limitará o número de encadeamentos de forma alguma. Pode haver chance de que, antes de iniciar um novo thread, o thread anterior possa ter terminado o trabalho, devido à sincronização. O processo de desova de um fio pode ser mais lento.

No entanto, você deve seguir isso até descobrir que existem muitos threads em execução e você está saindo da memória. E se você realmente deseja enfrentar isso antes do tempo, deve escolher algum mecanismo de bloqueio, algo como Semáforo.

Outras dicas

Outra possibilidade seria usar as filas JMS e colocar o e -mail enviando código em um feijão acionado por mensagem (ou através do Spring JMS). Você pode usar o servidor de aplicativos para controlar quantas instâncias simultâneas do seu MDB serão usadas e acelerar os e -mails de saída dessa maneira.

No Sping 3.0, você pode usar a anotação @async para executar a execução da tarefa, para que seu método seja executado posteriormente e o método seja retornado diretamente sem esperar que o email seja enviado.

@Async
public  void sendThroughSMTP(List<String> emails,String subject,String content){
//Send emails here, you can directly send lots of email
}

Em seguida, no contexto do aplicativo, você especifica e não se esqueça de adicionar XMLNs para esquema de tarefas.

Se você deseja atrasar a execução por certa quantidade de tempo, poderá usar a anotação @Scheduled no seu método.

Mais um tutorial sobre @async e @scheduled pode ser encontrado aqui:

http://blog.springsource.com/2010/01/05/task-scheduling-simplificações

Não tenho certeza se ela responde à sua pergunta, mas em vez de criar um novo tópico para cada e -mail e o chall Executor ou ExecutorService Como membro da sua classe, como implementação, você pode usar um ThreadpoolExecutor Com um tamanho de piscina de 1. Seu método sendmail enviaria o Runnables para o executor.

Spring @Transaction não é bem correto usado no seu caso. A melhor aposta é usar o método sincorizado e adicione algum pool de threads, se o seu método chamado por centenas de tempo. Mas acho que você não precisa do pool de threads aqui.

Se você usa thread para enviar e -mails de explosão, o que é sincronizando o método? Se um processo ligar para o seu método e enviar email, outro processo o chamará de método, mesmo o primeiro processo de email de envio ainda não terminou.

Se você pretende acelerar o processo de envio de email, precisará condir a fila (coleção) e proteger a coleção com o Synchronize Block. Crie outro processo para monitorar essa fila, se houver um item na fila, coloque -o e envie um email de explosão e aguarde até o envio do processo de e -mail e verifique novamente a fila, se houver algum item, continue enviando processo de email. Se não houver item na fila, faça o monitor Sleep por um pouco de tempo, se o tempo do sono terminar, verifique a fila novamente.

Faça do seu serviço um singleton e adicione synchronized para o seu método.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top